admin管理员组文章数量:1389772
I am reading about closures on MDN and I can't understand something in the following code:
var test = 1;
function makeFunc() {
var name = 'Mozilla';
function displayName() {
alert(name + ' ' + test);
}
return displayName;
}
//Create myFunction - test should still be set to 1 at this point
var myFunc = makeFunc();
test = 99999;
myFunc();
Why is Mozilla 99999
being printed instead of Mozilla 1
when the function was created while test
was assigned 1
? Shouldn't primitives by value types? I also don't think assignment gets hoisted, just declaration, pretty lost.
I am reading about closures on MDN and I can't understand something in the following code:
var test = 1;
function makeFunc() {
var name = 'Mozilla';
function displayName() {
alert(name + ' ' + test);
}
return displayName;
}
//Create myFunction - test should still be set to 1 at this point
var myFunc = makeFunc();
test = 99999;
myFunc();
Why is Mozilla 99999
being printed instead of Mozilla 1
when the function was created while test
was assigned 1
? Shouldn't primitives by value types? I also don't think assignment gets hoisted, just declaration, pretty lost.
4 Answers
Reset to default 4From the article you linked:
The reason is that functions in JavaScript form closures. A closure is the bination of a function and the lexical environment within which that function was declared. This environment consists of any local variables that were in-scope at the time the closure was created.
Here, name
is closed-over: It's a local variable at the time that the function was created. Though it's not a perfect analogy, you can think of it like the displayName
function has an internal pointer to the stack frame containing all the local variables that were around when you defined the function. If you were to pass in name
, you could see it being kept.
var test = 1;
function makeFunc(name) {
function displayName() {
alert(name + ' ' + test);
}
return displayName;
}
//Create myFunction - test should still be set to 1 at this point
var myFunc = makeFunc("one");
var myFunc2 = makeFunc("two");
test = 99999;
myFunc(); // bines closed-over name "one" with lexical scope test 99999
myFunc2(); // bines closed-over name "two" with lexical scope test 99999
Because test
is in lexical scope, not a closed-over local variable, both makeFunc
and makeFunc2
manipulate the same value in global scope, meaning that resetting test
can manipulate the output even after you've created the closures.
A closure does not merely capture a snapshot of test
when it is created, but captures the entire variable itself. This means that whenever the function myFunc
is called, it will print whatever the value of test
is when it was called, not the value of test
when the closure was created.
In other words, inside the closure, test
is still a variable, not a value. That means it can be changed and manipulated however you want, and anything that uses it will see those changes.
So for your code, as soon as you call myFunc()
on the last line, the runtime will evaluate the expression name + ' ' + test
, and since test is now 99999
, that's what you get.
makeFunc
itself returns a function which is called only after the assignment test = 9999;
. The variable test
is accessed from the 'outer' context (by closure).
This is because test
is not updated when makeFunc()
returns displayName
.
Take a look at name
which I removed from the method makeFunc()
scope to the global scope. When makeFunc()
executes, name
will be updated to Mozilla
from within the method scope. makeFunc()
then returns the function displayName()
without touching/updating test
. test
is only updated after the declaration of var myFunc = displayName() // return value of makeFunc()
.
Changing the value of test
after the declaration of myFunc()
will then alter the console.log()
value of test
.
var test = 1;
var name = "IE";
function makeFunc() {
name = 'Mozilla';
console.log("test inside makeFunc(): " + test);
function displayName() {
console.log(name + ' ' + test);
}
return displayName;
}
//Create myFunction - test should still be set to 1 at this point
console.log("test before myFunc declaration: " + test);
console.log("name before myFunc declaration: " + name);
var myFunc = makeFunc();
console.log("test after myFunc declaration: " + test);
console.log("name after myFunc declaration: " + name);
console.log("myFunc() before updating test");
myFunc();
test = 99999;
console.log("myFunc() after updating test");
myFunc();
本文标签: javascriptClosuresVariable Change After UseStack Overflow
版权声明:本文标题:javascript - Closures - Variable Change After Use - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744612872a2615760.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论