admin管理员组文章数量:1396755
Can anyone explain why document.write
part always outputs 10?
function creatFunctions() {
var result = new Array();
for (var i = 0; i < 10; i++) {
result[i] = function () {
return i;
}
}
return result;
}
var funcs = creatFunctions();
for (var i = 0; i < funcs.length; i++) {
document.write(funcs[i]() + "<br />");
}
I think the answer to this question is more thorough than the duplicate question, therefore worth keeping this post.
Can anyone explain why document.write
part always outputs 10?
function creatFunctions() {
var result = new Array();
for (var i = 0; i < 10; i++) {
result[i] = function () {
return i;
}
}
return result;
}
var funcs = creatFunctions();
for (var i = 0; i < funcs.length; i++) {
document.write(funcs[i]() + "<br />");
}
I think the answer to this question is more thorough than the duplicate question, therefore worth keeping this post.
Share Improve this question edited Apr 21, 2014 at 20:33 Blake asked Apr 21, 2014 at 13:42 BlakeBlake 7,54719 gold badges57 silver badges82 bronze badges 1- possible duplicate of Javascript closure inside loops - simple practical example – Felix Kling Commented Apr 21, 2014 at 13:58
5 Answers
Reset to default 9Sure.
In your for
loop, you reference i
. What you expect to be happening is that each closure gets a snapshot of i at the time the function is created, therefore in the first function it would return 0, then 1, etc.
What's really happening is that each closure is getting a reference to the external variable i
, which keeps updating as you update i
in the for
loop.
So, the first time through the loop, you get a function that returns i
, which at this point is 0. The next time you get two functions which return i
, which is now 1, etc.
At the end of the loop, i==10
, and each function returns i
, so they all return 10.
UPDATE TO ADDRESS QUESTION IN COMMENT:
It's a little confusing since you use i
in two different contexts. I'll make a very slight change to your code to help illustrate what's going on:
function creatFunctions() {
var result = new Array();
for (var i = 0; i < 10; i++) {
result[i] = function () {
return i;
}
}
return result;
}
var funcs = creatFunctions();
// NOTE: I changed this `i` to `unrelated_variable`
for (var unrelated_variable = 0; unrelated_variable < funcs.length; unrelated_variable++) {
document.write(funcs[unrelated_variable]() + "<br />");
}
... the functions that you create in your creatFunctions()
function all return i
. Specifically, they return the i
that you create in the for loop.
The other variable, which I've renamed to unrelated_variable
, has no impact on the value returned from your closure.
result[i] = function () {
return i;
}
... is not the same thing as result[2] = 2
. It means result[2] = the_current_value_of_i
Because you reference i
as a variable, which, when the function executes, has the value 10
. Instead, you could create a copy of i
by wrapping in in a function:
(function (i) {
result[i] = function () {
return i;
}
}(i));
The i
that you are returning inside the inner function - is the i
that was declared inside the for(var i=0...)
therefor - it is the same i
for all of the functions in result
and by the time you are calling the functions its value is 10 (after the loop ends)
to acplish what you wanted you should declare another variable inside the scope of the anonymous function
Because reference to "i" is boxed (enclosed) in your closure that you defined.
result[i] = function () {
return i;
}
And it just keeps reference to the "i" var which keeps changing with each iteration.
UPDATE
This is related to the function scope which defines variable context.
Hence, in JavaScript, there's no such thing as block scope (this
keywordfor
, if else
, while
, ...).
With that in mind, if you assign var funcs
to a function definitioncall, the function body ( var this
) will be bound to the global scopei
inside that function will reach the end of the for loop and stays there in memory. In this case i
is 10.
Unfortunately for you, since function scope puts every variable to the top, .var i
will be global as well
Although I was pletely wrong at first, I stand corrected and took the liberty to create the output of your script in this demo.
本文标签: JavaScript closure and scope chainStack Overflow
版权声明:本文标题:JavaScript closure and scope chain - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744132447a2592240.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论