2009-08-23 42 views
8

这里我做了两个对象;一个在构造函数中创建了存取方法,另一个在原型中创建。为什么会选择其中之一呢?原型与非,有什么好处?

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."); 
+1

请注意,在您的原型案例中,您(可能是无意中)创建了一个隐式全局变量'secret',它与构造函数中声明的(和未使用的)'secret'变量没有任何关系。该全局变量(全局对象的一个​​属性)是全局变量,将被'spy2'的所有实例共享 - 我猜这不是你想要做的。 – 2009-08-23 19:42:37

+0

谢谢。那确实是无意的。我改变了代码;这现在是正确的吗? 所以真的,原型不能修改对象的私有变量。 – 2009-08-23 19:53:46

回答

8

的原始differrence是,在你的第一个例子中,没有样机,该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

...哪些(为了提问者的利益)存在严重的内存使用分歧,应尽可能避免。 非原型版本的优点是您可以拥有真正的私有实例变量,因为成员函数是闭包。 (尽管不是它在提问者的问题中完成的方式)。 – 2009-08-23 19:40:54

+0

它可能存在严重的内存使用情况,但如果只创建少量实例,则无需担心。 – 2009-08-23 20:18:09

1

随着第二个版本,你最终得到一个更清洁的“构造函数”。

+1

是的,而且我最终还得到了一些与班级类似的活动,而不是班级的一部分。这让我很困扰。 – 2009-08-23 19:32:09

5

在第一个示例中,每当您实例化一个新对象时,您都会为对象的每个实例创建的新函数。在第二种情况下,仅创建该函数的单个副本,其被所有个实例使用。

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

顺便说一句,你的第二个例子不会像书面的那样工作。 spy2中的secret变量是构造函数的局部变量。在原型中的setSecretgetSecret函数中,您正在访问单个全局变量。

+0

啊,我明白了。所以如果我真的想要私有变量,我不能使用原型。 – 2009-08-23 19:49:09