Reputation: 2581
From what i know, a function say A defined within another function say B has access to local variables of B as well.
function B() {
var x = 10;
function A() {
console.log(x); //will result in 10
var y = 5;
}
console.log(y); //ReferenceError: y is not defined
}
However in the below example y gets printed. I know there is no such thing as block scope in javascript for "if block" but shouldn a declaration atleast be invisible outside of "if" i mean shouldnt var y be limited to if block?
function B() {
var x = 10;
if(1) {
console.log(x); //will result in 10
var y = 5;
}
console.log(y); will result in 5
}
Upvotes: 1
Views: 582
Reputation: 76413
JavaScript isn't truly block scoped. An if
or for
loop does not have its own scope. All variable declarations in any given scope (that is: global scope, or a function) are hoisted, and this visible anywhere inside that scope.
ECMAScript6 (Harmony) will, in all likelihood, introduce block-scope to JS, through the use of the new let
keyword see the wiki:
for (let i=0;i<12;++i)
{
console.log(i);//logs i
}
console.log(i);//reference error
There also seems to be some confusion as far as terminology is concerned here: a closure is not the same as a scope.
The snippet above is an example of block-scoped code. The variable i
is created at the start of the loop, and simply ceases to exist once the loop finishes. It is GC'ed (Garbage Collected). i
is no more, bereft of life it rests in peace. Closures are something different entirely: they rely on variables that are not GC'ed, but can't be accessed from outside code. They can only be accessed through the return value of the closure:
var someClosure = (function()
{//this function creates a scope
var x = 123;
return {
getX: function()
{
return x;
},
setX: function(val)
{
return x = val;
}
};
}());
console.log(x);//reference error
console.log(someClosure.getX());//returns 123, so "x" still exists
That being said:
You can mimic a block-scoped loop through the use of a closure, though. Functions are scoped, and a closure is a function or object that is returned by a function. That means that the return value of a function has access to the entire function's scope. See this answer for details.
Apply what is explained there, and work out why this loop is "pseudo-scoped":
var foo = [1,2,3,4,5,6],
largerThan3 = (function(arr)
{
var resultArr = [];
for (var i=0;i<arr.length;++i)
{
if (arr[i] > 3)
resultArr.push(arr[i]);
}
return resultArr;
}(foo));
console.log(i);//reference error...
Upvotes: 8
Reputation: 1305
nope. as you said - if blocks does not have their own closures in JS - which means everything is part of the outer closure (in this case - y is a local variable in B's closure). so it will be completely visible in B's body
Upvotes: 2