我理解闭包的大部分内容,但是这个例子让我很困惑。我将发布两个代码示例:第一个将是原始引用,他们解释闭包的工作,第二个将是代码,我添加了一些东西,但它没有给我我预期的结果。
这是他们给出的解释:
最后一个例子显示每次调用都会创建一个单独的闭包 局部变量。每个函数没有一个闭包 宣言。每次调用函数都有一个闭包。
实际代码:
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
console.log('num: ' + num +
'; anArray: ' + anArray.toString() +
'; ref.someVar: ' + ref.someVar + ';');
}
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;
现在,我不明白为什么obj.someVar ++更改了最后两行的结果,并且以下添加的num ++不会将最后两个num结果更改为8和9而不是7和8.有什么区别?
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
console.log('num: ' + num +
'; anArray: ' + anArray.toString() +
'; ref.someVar: ' + ref.someVar + ';');
}
}
num = 4
obj = {someVar: 4};
fn1 = newClosure(num, obj);
fn2 = newClosure(num+1, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
num++
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;
有人可以向我解释一下吗?
答案 0 :(得分:2)
为什么obj.someVar++
会更改最后两行的结果?
因为函数中的ref
是对象的引用。您更改了obj.someVar
,因此以下日志反映了此更改。
为什么以下添加的num ++不会将最后两个num结果更改为8和9而不是7和8?
由于您使用了关键字num
,因此var
变量与外部变量不同。 JavaScript是功能范围的,它们指的是不同的值。
我可以看到混乱的来源。您尝试传递someNum
和someRef
并对其执行“相同”操作(增量),但您有不同的行为。
您必须意识到的一点是num
的值是原始值4
,obj
的值是引用(类似于C中的指针) 。将引用视为指示内存地址的数字(但不完全是数字)。将它们传递给函数时,将复制值:
num
,将复制值4
。obj
,将复制值,在本例中为参考值。由于复制引用不会创建新对象,因此当您在函数外部更改值obj.someVar
时,更改将反映在函数中,因为它仍然引用同一对象。