我有这堂课:
function ctest() {
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2();
alert(this.var1);
}
var func2 = function() {
this.var1 = "huhu";
}
}
并称之为:
var myobj = new ctest();
myobj.func1();
不认为第二个警报会弹出“huhu”? func2是私有的,是不是可以访问var1公共变量?
如果私有函数无法访问公共变量,我该怎么办?
提前致谢!
答案 0 :(得分:17)
您需要为func2
的调用提供上下文:
this.func1 = function() {
alert(this.var1);
func2.call(this);
alert(this.var1);
}
如果没有上下文,调用将使用全局对象(即window
) - 您应该看到在运行当前代码时,在两个警报之间创建了window.var1
。
答案 1 :(得分:12)
函数与实例无关,因此,func2
的调用最终会在没有this
指向预期实例的情况下调用。
您可以修复调用以包含上下文:
function ctest() {
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2.call(this);
alert(this.var1);
}
var func2 = function() {
this.var1 = "huhu";
}
}
或者您可以使用想要的对象引用保留变量:
function ctest() {
var that = this;
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2();
alert(this.var1);
}
var func2 = function() {
that.var1 = "huhu";
}
}
答案 2 :(得分:2)
另一种选择是使用Function.bind
:
function ctest() {
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2();
alert(this.var1);
}
var func2 = function() {
this.var1 = "huhu";
}.bind(this);
}
请注意,浏览器对此的支持并不完美。
答案 3 :(得分:2)
JS中没有私有内容,但您可以使用closures来使用范围。
比如说,在您的示例中,您不需要将var1
公开为公共属性。您可以轻松地重写代码,如下所示:
function ctest() {
var var1 = "haha";
this.func1 = function() {
alert(var1);
func2();
alert(var1);
}
var func2 = function() {
var1 = "huhu";
}
}
因为func1
和func2
共享相同的范围 - 它们在同一个函数ctest
中定义 - 它们可以访问相同的变量。当然,在这种情况下,您没有公开var1
,因此:myobj.var1
将为undefined
。
如果您希望var1
作为属性公开,那么您需要bind func2
到您在构造函数中创建的对象实例:
function ctest() {
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2();
alert(this.var1);
}
var func2 = function() {
this.var1 = "huhu";
}.bind(this);
}
否则func2
将具有不同的上下文对象(this
)。如果浏览器不支持bind
并且您不想使用垫片(如上面的链接所示),您可以再次利用这些闭包:
function ctest() {
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2();
alert(this.var1);
}
var context = this;
var func2 = function() {
context.var1 = "huhu";
}
}
IMVHO不太优雅。
答案 4 :(得分:0)
function ctest() {
this.var1 = "haha";
this.func1 = function() {
alert(this.var1);
func2(this);
alert(this.var1);
}
var func2 = function(obj) {
obj.var1 = "huhu";
}
}
还有其他方法可以解决这个问题,请查看其他答案:)