我有以下这段代码:
var myNamespace = (function() {
// A private counter variable
var myPrivateVar = 0;
// A private function which logs any arguments
var myPrivateMethod = function(foo) {
console.log(foo);
myPrivateMethod2();
};
var myPrivateMethod2 = function(foo) {
console.log("Hi");
myPrivateMethod3();
}
var myPrivateMethod3 = function() {
console.log(3);
}
return {
myPublicVar: "foo",
myPublicFunction: function(bar) {
myPrivateVar++;
myPrivateMethod(bar);
},
myPublicFunction2: myPrivateMethod2
};
})();
当调用myPublicFunction时,此上下文是窗口,但是当调用myPublicFunction2时,此上下文是Object myNamespace。我希望它在两种情况下都是myNamespace,因为调用站点是myNamespace。为什么会有所不同?
答案 0 :(得分:2)
上下文不是由您定义对象的方式定义的,而是由调用方法的方式定义的。因此,根据如何进行此类调用,相同的函数可能一次将this
设置为某个对象,而另一次可能是其他时间。
可以使用bind
,call
,apply
和类似方法覆盖此行为。
当您拨打电话时,上下文将设置为myNamespace
:
myNamespace.myPublicFunction2()
...因为前缀。但是如果该函数会调用另一个函数,那么确定上下文的规则将决定嵌套函数调用中this
将是什么。
所以在这段代码之后:
myNamespace.myPublicFunction()
... this
将按照您的预期进行设置,但是一旦打电话就会丢失:
myPrivateMethod(bar);
那里没有前缀,因此window
是该函数运行时的上下文(在非严格模式下)。
您可以通过以下方式替换该呼叫来避免这种情况:
myPrivateMethod.call(this, bar);
同样,您希望对私有方法的其他调用执行相同的操作:
myPrivateMethod2.call(this);
// ...
myPrivateMethod3.call(this);