简体   繁体   中英

What is the difference between scope of these two functions

I am sorry if this is too naive, just got stuck with this while trying to answer another question. :) Here in the code below both bar.x and bar.y has similar/same function body (does it matter where the function is initially declared?). And I guess that the scope of a foo is lost when it is assigned to y , but still when I call bar.y() why is it not taking the global_var inside its closure? Is there a way both x and y can output 300 ?

 global_var = 2 var foo = function(){ console.log("y", global_var) } var bar = (function b(){ var global_var = 300; var x = function(){ console.log("x",global_var); }; var y = foo; return {x: x, y: y}; })(); bar.x(); //300 bar.y(); //2 setTimeout(bar.x); //300 setTimeout(bar.y); //2 

There is no closure involved in assigning foo to y . The function foo 's scope is determined where is is defined, which is at the top of your code sample, and the global_var inside the body of that function will always refer to the global_var variable that is (implicitly) defined in line 1, and not any other variable with the same name.

Assigning foo to y has no effect on the scope of that function. All that assignment accomplishes is that it makes foo accessible from a new variable.

Is there a way both x and y can output 300?

Not when the function is defined like that, but you could have something similar to what you're expecting if you use this :

 global_var = 2 var foo = function(){ console.log("y", this.global_var) } var bar = (function b(){ var global_var = 300; var x = function(){ console.log("x", this.global_var); }; var y = foo; return {x: x, y: y, global_var: global_var}; })(); foo(); // 2 bar.x(); // 300 bar.y(); // 300 setTimeout(bar.x); // 2 setTimeout(bar.y); // 2 setTimeout(bar.x.bind(bar)); // 300 setTimeout(bar.y.bind(bar)); // 300 

does it matter where the function is initially declared

Yes. The scope of a function is determined solely by where it is declared.

And I guess that the scope of a foo is lost when it is assigned to y

No. The scope is unchanged.

when I call bar.y() why is it not taking the global_var inside its closure?

Because the scope of a function is determined solely by where it is declared .

Is there a way both x and y can output 300?

Not by twiddling with scope.

You'd have to rewrite the function to get the data from somewhere else, eg from object properties.

 var global_object = {}; global_object.data = 1; global_object.foo = function() { console.log("y", this.data); }; var bar = (function b() { var local_object = {}; local_object.data = 2; local_object.x = function() { console.log("x", this.data); }; local_object.y = global_object.foo; return local_object; })(); bar.x(); // 2 bar.y(); // 2 setTimeout(bar.x.bind(bar)); // 2 setTimeout(bar.y.bind(bar)); // 2 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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