对JavaScript闭包的误解

时间:2012-01-04 15:01:39

标签: javascript closures

我是JavaScript的新手,在理解这段代码时遇到了问题:

function addProperty(o) {
   var value;

   o["get"] = function()  { return value; }
   o["set"] = function(v) { value = v; }
}

var a = {};
addProperty(a);
var b = {};
addProperty(b);

a.set(4);
b.set(5);
print("a is " + a.get() + "; b is " + b.get());

打印(在v8 / d8中)a is 4; b is 5。如果我注释掉var value;行,我会a is 5; b is 5。 '价值'对象在哪里,为什么有两个?感谢。

2 个答案:

答案 0 :(得分:12)

value变量是addProperty的本地变量。第一次调用addProperty时,会创建一个新的value,两个函数都会关闭。第二次调用addProperty时,会创建第二个value,其中两个新函数关闭。

删除var会在所有功能共享的value对象上创建全局 window

也许你的意思是这样做:

function createPropertyMgr() {
    var value;
    return function(o) {
       o["get"] = function()  { return value; }
       o["set"] = function(v) { value = v; }
    }
}

var addProperty = createPropertyMgr();

这个新的addProperty函数会关闭一个value,无论它被调用多少次。我不确定我是否了解用例,但这应该证明其不同之处。

答案 1 :(得分:1)

如果未在函数内显式声明变量,则将其范围假定为全局变量。即在你的第二种情况下,因为你没有明确地将value声明为函数addProperty()的本地,所以它被视为全局。

但是当你在一个函数中明确地声明它时,它就变成了函数的本地。每次调用函数时,都会在堆栈上创建函数局部变量的新副本(重要的是,只要有对它的引用,它就会保留在堆栈中)