JavaScript和匿名函数中闭包的细节



此代码导致"!"被记录在控制台上。

var g = {};
(function() {
    var t = this;
    t.x = "x";
    g.a = function() {
        console.log(t.x);
    };
})();
(function() {
    var t = this;
    t.x = "!";
    g.b = function() {
        console.log(t.x);
    };
})();
g.a();

匿名函数是否共享this?我用错this了吗?我真的不明白这里发生了什么。

我希望g.a()继续返回第一个匿名函数中定义的x的值。

如果有区别的话,我会使用node.js。

在立即函数中,this全局对象[docs]。因此,在这种情况下,在两个函数中,this确实引用了同一个元素,并且您正在用第二个调用覆盖x

this所指的对象由函数的调用方式决定。

  • 如果只使用funcName();执行函数,则this引用全局对象
  • 如果函数被指定给对象的属性,则obj.funcName()this指代该对象
  • 如果使用new运算符new funcName();调用函数,则this引用从函数原型继承的空对象

也可以使用call[docs]apply[docus]显式设置this


您可以在两个函数中创建一个新对象,而不是引用this

var t = {};

附加说明:无论是在浏览器中运行代码还是使用node.js运行代码都没有区别。全局对象是规范的一部分,必须由执行环境提供。在浏览器中,它是window对象,我不知道它在node.js中是什么,但只要它符合规范,就无关紧要。

Felix Kling是正确的长答案。但我想与我认为你真正想要的一致:

var g = {};
(function() {
    var x = "x";
    g.a = function() {
        console.log(x);
    };
})();
(function() {
    var x = "!";
    g.b = function() {
        console.log(x);
    };
})();
g.a(); // "x"
g.b(); // "!"

现在g.a()g.b()都打印出x,但每个函数都有自己单独的x,与闭包共享。如果这些变量应该是私有的,并且只能在内部访问这些函数中的每一个,那么这就是隐藏它们并通过多次调用持久化它们的方法。

当我在Chrome的调试器中查看此脚本时,如您所示,两个匿名函数中的"this"值都设置为全局变量"window"。这意味着每个匿名函数都设置了window.x的值,因此最后一个执行的函数获胜,并且是幸存的值,从而在第二个匿名函数执行后设置window.x == "!"

我不清楚你期望"这"是什么,也不清楚你实际上试图用这个代码实现什么,所以我不知道该建议什么替代方案。如果你只想让匿名函数中的前一个状态在内部函数中继续存在,那么你可以只依赖局部变量(它将在闭包中继续存在(,而根本不使用"this"引用。Squeegy的例子说明了这一点。

最新更新