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

时间:2011-07-02 20:23:22

标签: javascript node.js

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

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。

3 个答案:

答案 0 :(得分:4)

在直接功能中,this指的是global object [docs]。所以在这种情况下,在两个函数中this确实引用相同的元素,并且在第二次调用时覆盖x

this引用的对象取决于函数的调用方式。

  • 如果您只使用funcName();执行某项功能,则this会引用全局对象
  • 如果将函数分配给对象的属性,obj.funcName(),则this引用该对象。
  • 如果使用new运算符new funcName();调用该函数,this指的是从函数原型继承的空对象。

您还可以使用call [docs]apply [docs]明确设置this


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

var t = {};

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

答案 1 :(得分:3)

菲利克斯克林是一个正确的答案。但我想用我认为你真正想要的东西来填充:

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与闭包共享。如果这些变量应该是私有的,只能在每个函数内部访问,这就是你隐藏它们并通过多次调用保持它们的方式。

答案 2 :(得分:1)

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

我不清楚你对这个代码的期望是什么,或者你实际上想用这个代码完成什么,所以我不知道建议的替代方案。如果你只是希望匿名函数中的先前状态能够在内部函数中存活,那么你可以只依赖局部变量(它将在闭包中存活)并且根本不使用“this”引用。 Squeegy的例子显示了。