模块模式Javascript - 这个绑定

时间:2017-03-28 18:47:16

标签: javascript

我有以下这段代码:

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。为什么会有所不同?

1 个答案:

答案 0 :(得分:2)

上下文不是由您定义对象的方式定义的,而是由调用方法的方式定义的。因此,根据如何进行此类调用,相同的函数可能一次将this设置为某个对象,而另一次可能是其他时间。

可以使用bindcallapply和类似方法覆盖此行为。

当您拨打电话时,上下文将设置为myNamespace

myNamespace.myPublicFunction2()

...因为前缀。但是如果该函数会调用另一个函数,那么确定上下文的规则将决定嵌套函数调用中this将是什么。

所以在这段代码之后:

myNamespace.myPublicFunction()

... this将按照您的预期进行设置,但是一旦打电话就会丢失:

myPrivateMethod(bar);

那里没有前缀,因此window是该函数运行时的上下文(在非严格模式下)。

解决方案

您可以通过以下方式替换该呼叫来避免这种情况:

myPrivateMethod.call(this, bar);

同样,您希望对私有方法的其他调用执行相同的操作:

myPrivateMethod2.call(this);
// ...
myPrivateMethod3.call(this);