JavaScript closure的一个问题

本文探讨了JavaScript中闭包的工作原理,通过具体实例解释了为何闭包内的函数仅能更新最近创建的变量副本。文章提供了详细的代码示例来帮助读者理解闭包和作用域的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

down vote
favorite
function f1() {    
    var n = 999;    
    nAdd = function() {
        n += 1
    }    
    function f2() {      
        alert(n);    
    }    
    return f2;  
}  
var result1 = f1();
var result2 = f1();
var result3 = f1();  

nAdd();
result1();  //999
result2(); //999
result3(); //1000

以上是困惑的问题?为什么nAdd()影响最近的闭包。
stackoverflow的两个答案,合起来能很好的理解这个问题。

1.进一步明白细节的回答

It has to do with when nAdd is assigned the function. Note that when you create a closure, a new "copy" (for lack of a better word) of the local variables are created. Thus, result1's n is different from result2s n which is different from result3's n. They are seperate, and each closure cannot access another closure's n.

Look at this line:

nAdd = function() {
     n += 1;
}

This assigns nAdd a new closure each time. Each time, this closure will only affect the most recent "copy" of n.

So when you are doing.

var result1 = f1(); // assign nAdd for the first time, referring to result1's n.
var result2 = f1(); // re-assign nAdd, now it affects result2's n.
var result3 = f1(); // re-assign nAdd, now it affect result3's n.

nAdd got assigned a new closure each time. The last time, nAdd got assigned a closure with result3's copy of n.

Thus, when you do nAdd(), you only increment result3's n.

Here's an example that might clear things up.

function f1() {    
    var n = 999;    
    nAdd = function() {
        n += 1
    }    
    function f2() {      
        alert(n);    
    }    
    return f2;  
}  
var result1 = f1();
var nAdd1 = nAdd;
var result2 = f1();
var nAdd2 = nAdd;
var result3 = f1();  
var nAdd3 = nAdd;

nAdd3();
result1();  //999
result2(); //999
result3(); //1000
nAdd1();
result1(); // 1000
nAdd1();
result1(); // 1001
nAdd2();
result2(); // 1000
nAdd();
result3(); // 1001 (the most recent nAdd result3's n).

To further elaborate, consider what would happen if you did this instead:

var result1 = f1();
nAdd();
var result2 = f1();
var result3 = f1(); 

result1(); // 1000
result2(); // 999
result3(); //999

Or this:

var result1 = f1();
var result2 = f1();
nAdd();
var result3 = f1(); 

result1(); // 999
result2(); // 1000
result3(); // 999

It becomes obvious that nAdd updates only the most recent invocation's n.!

2.调用本质的回答

First, you need to be clear about the following thing:

nAdd is a global scoped function. But it is using a local scoped variable n.

Every time you re-create f1(), the pointer of nAdd function will change.

Finally it will changed to the closest f1() closure and the n variable inside nAdd function will also point to the closest f1() closure. So it can only change the value of the closest one.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值