Reputation: 15566
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
Upvotes: 0
Views: 60
Reputation: 101680
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
Upvotes: 1
Reputation: 943564
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, e.g. 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
Upvotes: 1