2012-02-02 88 views
2

覆盖例如如何在在公共职能

var MyClass = function(){ 

    var that = this; 

    var my_var = "I want this"; 

    var another_var = "this one is easy"; 

    this.aPublicFunc = function(my_var){ 

    console.log(my_var); // logs "I don't want this"; 
    console.log(another_var); // logs "this one is easy"; 
    console.log(this.my_var); // logs undefined which makes sense as the this context is the context of the calling function. 
    console.log(that.my_var); // logs undefined 
    }; 
}; 

var an_object = new MyClass(); 
var an_object.aPublicFunc("I don't want this"); 
+1

为什么你不重命名你的第二个'my_var'? – deceze 2012-02-02 12:18:44

+1

答案是:你没有。更好地命名你的变量和函数参数。 – 2012-02-02 12:21:12

+2

'my_var'和'another_var'是你的例子中的全局变量。全局变量和局部变量不是神奇地成为你创建的对象的属性,所以'that.my_var'不能工作,除非你明确地指定它。在你的例子中,当调用'an_object.aPublicFunc(...)''this'时也指'that'。 – 2012-02-02 12:21:56

回答

2

像你一样拥有my_var的私有变量只能从构造函数中的代码和其范围内定义的函数(如aPublicFunc())中调用。而且,要访问它们,您必须使用正常的JavaScript引用。当您使用相同的名称定义参数为aPublicFunc()时,您将隐藏该外部范围变量,并且没有办法按照定义来达到它。这些私有变量不是对象的成员,它们是在闭包中捕获的变量。在JavaScript中,在闭包中访问变量的唯一方法是从闭包范围内的代码,如果没有任何内容覆盖它们的名称,则只能覆盖它们。

您的简单解决方案是将参数或局部变量的名称更改为略有不同的名称。如果你真的希望他们看起来很相似,然后把下划线在这样其中的一个前端:

var MyClass = function(){ 

    var that = this; 
    var _my_var = "I want this"; 
    var _another_var = "this one is easy"; 

    this.aPublicFunc = function(my_var){ 

    console.log(_my_var); // logs "I want this"; 
    console.log(_another_var); // logs "this one is easy"; 
    console.log(my_var); // logs "I don't want this" 
    }; 
}; 

var an_object = new MyClass(); 
var an_object.aPublicFunc("I don't want this"); 

或使其论点这样一点更加明显:

var MyClass = function(){ 

    var that = this; 
    var my_var = "I want this"; 
    var another_var = "this one is easy"; 

    this.aPublicFunc = function(new_my_var){ 

    console.log(my_var); // logs "I want this"; 
    console.log(another_var); // logs "this one is easy"; 
    console.log(new_my_var); // logs "I don't want this" 
    }; 
}; 

var an_object = new MyClass(); 
var an_object.aPublicFunc("I don't want this"); 

你可以看到这最后一个工作在这里:http://jsfiddle.net/jfriend00/Jeaaz/

+0

谢谢,清楚的解释。 – SystemicPlural 2012-02-15 08:50:33

2

不重写公共函数访问私有变量。它使得代码不易读和更令人困惑。

+0

在这种情况下,它是一个二传手。所以有相同的名字是有道理的。但如果我看不到它,我无法设置它。 – SystemicPlural 2012-02-02 12:43:34

+0

即便如此,它仍然让IMO感到困惑。它们并不代表同一件事,所以将它们称为同一件事情是有道理的。该参数表示一个新值/一个输入值,而来自外部范围的其他my_var表示该对象的旧/当前状态。假设你设法从外面读取my_var,你会怎么知道,单独看着那条线,不管你是在读旧的/当前的状态还是正在读取新的状态?如果名称/参考中的某些内容将两者区分开来,它可帮助提高可读性。 newvalue,currentvalue,state.value等 – Supr 2012-02-02 13:03:49

+0

在其他语言中,你会使用this.my_var = my_var,不幸的是,这里唯一的办法就是让my_var成为public,这正是我想要避免的。它是私人的,也避免了在其他地方访问它的问题。 – SystemicPlural 2012-02-02 13:37:20