在JavaScript中创建类时,有一个明确的原因使用原型。
使用更少的内存。
当method使用定义this.methodName一个新的副本创建的每个新的对象被实例化时。我们来看一个例子。
在大多数面向对象的编程语言中,类具有构造函数。构造函数是一种初始化函数,每次创建类的新实例时都会调用该函数。通常,使用实际的类名或关键字定义构造函数名称constructor:
// In Java
public class Animal { private String _name; // constructor function public Animal(name){ // this content will be executed when an instance is created: // Ex: Animal cat = new Animal('cat'); _name = name; }}复制代码
// In PHP
class Animal { private $name; public function __constructor($name){ // this content will be executed when an instance is created: // Ex: $dog = new Animal('dog'); $this->name = $name; }}复制代码
但是在JavaScript中怎么样?我们有构造函数吗?是的,我们这样做,只有JavaScript中的所有东西都是奇怪的,所以构造函数本身就是类/函数/构造函数。
// In JavaScript
function Animal(name){ // this is the class and the constructor at the same time. // Ex: var cat = new Animal('cat') this.name = name;}复制代码
所以当我们调用new Animal()构造函数时立即调用。这是性能问题发生的地方。想象一下,我在构造函数中定义了三个函数,这意味着每一次,这些函数都是重新定义的。
function Animal(){ this.walk = function(){}; this.talk = function(){}; this.jump = function(){};}复制代码
我们每次都在创建重复的功能。如果我创建两个或三个对象,那么问题可以忽略不计。但是如果我们创造了一群动物,我们就开始看到我们的记忆在增长,因为在每只动物身上我们都会在运行时/实例时创建一个全新的方法。
var cat = new Animal();var dog = new Animal();(cat.walk === dog.walk) // false 复制代码
第一个对象的步行与第二个对象的步行不同,因为每个对象都是在实例化期间创建的。换句话说,Animal walk()在实例化之前不知道该方法是否存在。
该问题的解决方案是使用Prototypes。它的作用是允许我们一次定义方法,作为蓝图,并让每个实例从中构建。
function Animal(){};Animal.prototype.walk = function(){};Animal.prototype.talk = function(){};Animal.prototype.jump = function(){};复制代码
现在,任何新实例在创建之前都会显示该类的蓝图。所以每次散步都是散步,每次跳跃都是跳跃:
var cat = new Animal();var dog = new Animal();(cat.walk === dog.walk) // true复制代码
想象一下创建一个虚拟DOM,其中每个DOM元素都有一些方法。如果您使用非原型方法,this则将为每个虚拟DOM元素重新创建每个方法。在您注意到应用程序速度变慢后不久。但是使用原型和方法只定义一次因此占用更少的内存。这类似于jQuery如何定义DOM元素的方法。.css例如,它们不为每个元素创建新元素,它们使用原型定义一次。
使用原型的唯一不便是没有简单的方法来创建私有方法或变量。
function Animal(){ // this varialbe is private var private_var = 10; // this function is public this.walk = function(){}; // this function is private function dance(){}}复制代码
如果要创建大量实例,请使用原型。