这里我做了两个对象;一个具有在构造函数中创建的访问器方法,另一个在原型中。为什么选择其中一个而不是另一个呢?
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.");
答案 0 :(得分:8)
原始的不同之处在于,在第一个示例中,如果没有原型,getSecret
和setSecret
函数实现将驻留在 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
变量是构造函数的本地变量。在原型中的setSecret
和getSecret
函数中,您正在访问单个全局变量。
答案 2 :(得分:1)
使用第二个版本,您最终会得到一个更清晰的“构造函数”。