Prototype vs. Not,有什么好处?

时间:2009-08-23 19:22:48

标签: javascript prototype

这里我做了两个对象;一个具有在构造函数中创建的访问器方法,另一个在原型中。为什么选择其中一个而不是另一个呢?

function spy1(name){
  this.name = name;
  var secret;
  this.setSecret = function(message){
    secret = message;
  };
  this.getSecret = function(){
   return secret;
  };
}

function spy2(name){
  this.name = name;
  this.secret;
  /* (see comment) was:
  var secret;
  */
}
spy2.prototype.setSecret = function(message){
  this.secret = message;
  /*was:
  secret = message;
  */
};
spy2.prototype.getSecret = function(){
  return this.secret;

  /*was:
  return secret;
  */
};

bond = new spy1("007");
smart = new spy2("86");

bond.setSecret("CONTROL is a joke.");
smart.setSecret("The British Secret Service is for sissies.");

3 个答案:

答案 0 :(得分:8)

原始的不同之处在于,在第一个示例中,如果没有原型,getSecretsetSecret函数实现将驻留在 spy1的每个实例上。

在第二个例子中,函数是在原型上定义的,所有实例都直接引用它们,你可以测试它:

var bond = new spy1("007"),
    bond2 = new spy1("007");

bond.getSecret === bond2.getSecret; // <-- false since they are two functions

var smart = new spy2("86"),
    smart2 = new spy2("86");


smart.getSecret === smart2.getSecret; // <-- true since is the same function
                                      // on all instances

还要注意@ T.J。注释,在你的第二个例子中,使用原型,你无权访问构造函数闭包,为此你创建了一个window.secret全局变量。

如果您打算使用privileged methods,扩展原型不是一个选项,需要访问构造函数范围内定义的变量的所有方法都需要在其中声明...

另请参阅:Closures

答案 1 :(得分:5)

在第一个示例中,每当实例化一个新对象时,都会为对象的每个实例创建新函数。在第二个中,只创建了一个函数的副本,该副本由所有实例使用。

第二种方式可以节省内存。您还可以使用prototype chaining来实现继承。

顺便说一下,你的第二个例子不会按照书面形式工作。 secret中的spy2变量是构造函数的本地变量。在原型中的setSecretgetSecret函数中,您正在访问单个全局变量。

答案 2 :(得分:1)

使用第二个版本,您最终会得到一个更清晰的“构造函数”。