麻烦理解Javascript关闭示例
问题描述:
我明白关闭的大部分内容,但后来这个例子让我颇为困惑。我将发布两个代码示例:第一个是原始引用,他们解释了关闭的工作原理,第二个代码是我添加内容的代码,但没有给出我期望的结果。麻烦理解Javascript关闭示例
这是他们给出的解释是:
最后一个例子表明,每呼吁 局部变量创建一个单独的封闭。每个功能 声明没有单个关闭。每个函数调用都有一个闭包。
的实际代码:
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;
有人可以解释这一点吗?
答
-
为什么
obj.someVar++
改变的结果的最后两行?因为
ref
中的函数是对象的引用。您更改了obj.someVar
,因此以下日志反映了此更改。 -
为什么下面的另外的num ++不是最后两个NUM结果更改为8和9,而不是7和8?
由于您使用了关键字
var
,因此num
变量与外部变量不同。 JavaScript是函数范围的,它们指的是不同的值。
我可以看到那里的混乱来自。您试图通过someNum
和someRef
并对它们执行“相同”操作(增量),但您获得了不同的行为。
你必须认识到的一件事是num
的值是一个原始值4
,并且obj
的值是一个引用(类似于C中的指针)。将参考视为指示内存地址的数字(但不完全是数字)。当你将它们传递到函数,值复制:
- 为
num
,价值4
被复制。 - 对于
obj
,复制该值(在本例中为参考)。
由于复制引用不创建一个新的对象,当你改变函数外部的值obj.someVar
,这些变化将在功能上体现,因为它仍然指的是同一个对象。
令人惊讶的是,我现在明白了。谢谢! –
我真的开始享受Javascript及其所有细节。再次感谢您的回应。 –