Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've stumbled upon a JavaScript variable behavior I could not explain.

According to JS docs on var keyword :

The scope of a variable declared with var is the enclosing function or, for variables declared outside a function, the global scope (which is bound to the global object).

Also it is known that global variables become properties of the global object - 'window' in the browser environments and 'global' in node.js This means if a variable is declared with a 'var' keyword inside a function it becomes local and does not get into the global object.

This example proves it:

(function(){
    var t = 1;
    console.log(t in window, t); // outputs: false 1
}());

jsfiddle link

So far so good. However if variable is not initialized it does become a property of the window object despite the fact it is in the function scope.

(function(){
    var t;
    console.log(t in window, t); // outputs: true undefined
}());

jsfiddle link

Why does it happen ? Where can I learn the details of this behavior ? Regular tutorials don't seem to cover this.

Thanks in advance.

[EDIT]: Thanks to the Pointy it is clear now scope works as expected. I simply had a wrong understanding of the 'in' operator behavior. According to 'in' docs it coerces left hand operand to the number or string and looks for such index or property name in the right hand object. So in the example one it was equal to

'1' in window

which was false

and in the example two it was

'undefined' in window

which was true.

share|improve this question
    
The variable is still there... it just doesn't have a value. var a; console.log(typeof a); will be undefined no matter where you put it. –  Brad May 2 '13 at 14:16
    
I shall now name all my variables after African countries for the day. –  Dave Newton May 2 '13 at 14:17
    
Ha ha @DaveNewton actually I was confused, but I confess that that's been a standard diagnostic test I've employed for years in "WTF" situations :-) –  Pointy May 2 '13 at 14:18
    
@Brad undefined value is predictable. The question is why the variable is global at the declaration time and becomes local only after initialization. –  Igor Malyk May 2 '13 at 14:22
add comment

2 Answers

up vote 3 down vote accepted

The issue is that your test code is using the in operator erroneously. What it's actually testing is whether the name "undefined" is defined in window, not "t". Why? Because the left-hand operand of in is coerced to a string. Because "t" is undefined, it's coerced to the string "undefined", and indeed that property name is present in the global context.

Change the test to

console.log("t" in window, t);
share|improve this answer
    
Your suggestion seems to be valid. Thanks a lot. I was totally puzzled and was thinking something was wrong with the scope but the reason was my wrong understanding of the 'in' operator. –  Igor Malyk May 2 '13 at 14:40
add comment

access to a variable declared by

var t;

gives you:

console.log(t);
undefined

console.log(undefined === t)
true

undefined is a property of window

console.log(undefined in window);
share|improve this answer
    
Thanks for your help. –  Igor Malyk May 2 '13 at 14:47
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.