Javascript Revealing Module Pattern - 这个和内部函数调用

时间:2013-09-19 09:11:57

标签: javascript revealing-module-pattern

我最近在我的Javascript中使用Revealing Module pattern来帮助构建我的代码并且一切都很顺利。但是,我对此代码段感到有点困惑:

function vm() {
    var pub = function () {
        alert("from pub: " + this);
        pri();
    },
    pri = function () {
        alert("from pri: " + this);
    };

    return {
        pub: pub,
        pri: pri
    };
}
var it = new vm();
it.pub();
it.pri();

JSFiddle

当我直接致电pub()pri()时,this会引用vm的当前实例。但是,当我从pri()内调用pub()this突然this已恢复为引用全局窗口对象。我认为揭示模块模式的目标之一是删除this的问题但似乎从另一个函数中调用函数时我失去了{{1}}的值。

有没有人知道为什么会这样,如果有办法让它工作而不必传递对当前对象的引用?

3 个答案:

答案 0 :(得分:8)

您的示例结合了调用函数的四种方法中的三种。

构造函数调用

var it = new vm();

function vm内,this指的是您要返回的对象实例。这是预期的。

方法调用

it.pub();

function pub内部,这指的是it 引用的对象实例相同的对象实例。再次,这是预期的。

函数调用

pri();

function pri内,this指的是全局对象。这不是预期的,并且被认为是JavaScript语言中的错误。使用方法调用模式调用'pub'函数,因此很自然地假设this在内部使用时应始终指向当前函数/对象。

一种补救方法是将返回的对象存储在vm方法内的局部变量中,然后由于作用域,pubpri方法将能够安全地引用对象实例。

function vm() {
    var pub = function () {
        alert("from pub: " + that);
        pri();
    },
    pri = function () {
        alert("from pri: " + that);
    };

    var that = {
        pub: pub,
        pri: pri
    };

    return that;
}

答案 1 :(得分:1)

pri()内调用pub实际上会调用范围内的已捕获pri变量。在没有目标对象的情况下调用它会将this设置为全局(窗口)对象。

您可能想了解this在Javascript中的工作原理,因为它与您可能知道的其他面向对象语言非常不同。 this是动态的,并根据您调用方法的方式而变化。

在您的情况下,修复很容易:调用函数:this.pri()。这将正确调用当前pri对象的this成员(即var it),this设为this ...如果此句话为感!

永远不要认为你可以在javascript代码中省略this.,就像在C#或Java中一样。

答案 2 :(得分:0)

正如其他人对它的解释一样,我只是为您提供一种技巧,以保持您的背景紧密。您可以使用bind来锁定当前上下文的对象。注意,并非所有浏览器都支持它(旧版本的IE失败)。除了技术有爱好者和反对者。

return {
  pub: pub.bind(this),
  pri: pri.bind(this)
};

<强> http://jsfiddle.net/zreFY/1/