简体   繁体   English

了解JavaScript闭包-冻结变量传递给回调

[英]Understanding JavaScript Closures - Freeze variable passed to callback

I do not yet have a basic understanding of JavaScript closures; 我还没有对JavaScript闭包的基本了解;

I have a question regarding a specific situation that perhaps is also basic and common example: 我有一个关于特定情况的问题,这也许也是基本且常见的示例:

Count from 1 to 3 in 3 seconds 在3秒内从1数到3

See JSFiddle here: http://jsfiddle.net/nAh8x/ 在这里查看JSFiddle: http//jsfiddle.net/nAh8x/

The code: 编码:

var i,
    t;

t = 0;

// Case A

for( i=1; i<=3; i++ ) {
    setTimeout( function() { log(i); }, t );
    t += 1000;
}

// Case B

for( i=1; i<=3; i++ ) {
    setTimeout( wrapper(i), t );
    t += 1000;
}

function wrapper(i) {
    return function() { log(i); };
}

// Log utility function

function log(msg) {
    $('#log').append( msg + '<br />' );
}

Case A doesn't work. 情况A不起作用。

It's clear to me why: every time the function inside setTimeout is called and accesses the i variable, its value has already reached 4. 我很清楚为什么:每次调用setTimeout内部的函数并访问i变量时,其值已经达到4。

Case B works. 情况B有效。

When wrapper(i) is called it returns wrapper(i)被调用时,它返回

function() { log(i); };

and the above return value (a function) is what goes inside setTimeout. 上面的返回值(一个函数)是setTimeout内部的内容。 What goes inside setTimeout is exactly the same as Case A setTimeout内的内容与案例A完全相同

But this time, the i variable have been "frozen" with the value at the time of the call. 但是这一次, i变量已经被“冻结”了调用时的值。

Why using the wrapper function let the passed value to be frozen? 为什么使用包装器函数将传递的值冻结?

That's not completely clear to me. 这对我来说还不是很清楚。

Closure is an environment which is created with variables scope and nested function by calling of outer function, 封闭是通过调用外部函数,使用变量作用域和嵌套函数创建的环境,

Every time the wrapper() is called there would created each different environment for below's function 每次调用wrapper() ,都会为下面的函数创建每个不同的环境

function wrapper(i) {
    return function() { log(i); };
}

Here is the i 's value would be same as when wrapper() is invoked. 这是i的值与调用wrapper()时的值相同。 Each time the i 's value would be private for that particular environment which made by invoking wrapper() outer function. 每次通过调用wrapper()外部函数生成的特定环境, i的值都是私有的。

The wrapper function has it's own i that is locally scoped to it. 包装函数具有它自己的i ,该i在本地范围内。

This receives the value of the other i at the time wrapper is called. 在调用wrapper时,它将接收另一个i

It might be clearer if you rewrote it as: 如果将其重写为:

function wrapper(notI) {
    return function() { log(notI); };
}

The variable i used inside wrapper is the one the has been passed (as a copy ) as the formal parameter to wrapper . iwrapper使用的变量是已作为wrapper的形式参数传递(作为副本 )的变量。 It's not the same i as the one inside your for loop - you could rename that variable to anything you like and the code would still work. i和您的for循环中的那个不一样-您可以将该变量重命名为您喜欢的任何名称,并且代码仍然可以工作。

It's frozen because it has the value it had each time wrapper was originally called. 之所以冻结,是因为它具有每次调用wrapper都具有的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM