我试图理解闭包,并使用下面的代码。我希望i的值在所有对象中都是相同的,因为闭包保持对外部函数变量的引用。
function Test(){
var i=10;
return{
get:function(){return i;},
inc:function(){i++;}
}
}
var test1= Test();
var test2=Test();
test1.get(); //outputs 10
test1.inc();
test2.get(); //outputs 10, I am expecting it to be 11
我对闭包的理解是否正确,我是否甚至在这种情况下创建了闭包?我是封闭的新手,详细解释会很棒。谢谢。
答案 0 :(得分:2)
正如其他人所提到的,你基本上创造了两个闭包。
理解闭包的最简单方法是它是全局变量概念的概括。实际上,javascript中的全局变量只不过是全局范围内的闭包。
闭包是函数体可以引用外部范围中的变量的机制。如上所述,全局变量只不过是一个闭包:
var x;
function x_plus_plus () {
x++; // this variable is captured by a closure
}
每个范围都允许您创建一个闭包。因此除了全局范围之外,您还可以在其他函数内创建闭包。对我个人而言,最能说明闭包内容的最小示例代码是IIFE,它定义了两个共享变量的函数:
var incr;
var val;
(function(){
var x = 0; // shared with the functions below var via closure
incr = function(){x++};
val = function(){return x};
})();
incr();
incr();
console.log(val()); // outputs 2 because the functions share x
console.log(x); // syntax error - x does not exist in this scope
请注意,闭包是变量和在该变量范围内声明的函数之间发生的事情。它不是变量和变量声明的函数之间发生的事情:
function () { <─────┐
├── this is not a closure
var foo; <───────┘
}
function () {
var foo; <────────────────┐
├── this is a closure
function bar () { │
do_something(foo); <───┘
}
}
var x; <───────────────┐
├── this is also a closure but we
function y () { │ normally call it "global variable"
do_something(x); <───┘
}
旁注:js中的全局变量实际上有点独特,因为它们也是全局(窗口)对象的属性。但从理论上讲,他们的表现就好像他们是一个闭包的实例。关键在于将闭包视为类似全局变量的机制是理解它们的最简单方法。
答案 1 :(得分:0)
您已创建了2个不同的实例。因此分配了2个不同的内存,这意味着2个不同的闭包。不要以为在关闭时已经在实例中共享内存而感到困惑。
test1.get(); //10
test1.inc();
test1.get(); //11
test2.get(); //10
如果要创建共享变量,请阅读原型。因为prototype是与函数引用的实时连接。