0

In JavaScript, why do both of the following return true?

> var a; 
undefined
> "a" in window;
true
> a in window;
true

Is there some kind of type coercion going on, or does JavaScript store a as both a string and as a variable in the window?

Please feel free to rewrite the title of this question - I wasn't sure exactly how to describe this confusing phenomenon.

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
flossfan
  • 10,554
  • 16
  • 42
  • 53
  • I did - the first returns false, the second is a `ReferenceError`. – flossfan Jan 31 '14 at 08:10
  • that's because b is undefined, and the way your console evaluates the expression (an elaborate `eval` system), it can't scope-scan and create a new implied global... but that's besides the point here. Not that I take offense, but I'd like to know why you accepted the answer that was posted _after_ mine, contained less information and just references my answer for completeness – Elias Van Ootegem Jan 31 '14 at 08:19

2 Answers2

6

No, you declared a variable called a, which is initialized to undefined. This variable is global, so it can be accessed as a sort-of property of the global object (window), so:

var a = {};//an obejct
var b = {};//another
b === a //false, two separate objects, of course but
window.a === a;//true

That's why 'a' in window is true. It's similar to window.hasOwnProperty('a');. Similar, not the same thing.

The second check you did (a in window) is evaluated to undefined in window, in turn the value undefined is stringified, so the expression is finally evaluated to 'undefined in window', which is always going to be true.
I admit, this is confusing, because undefined is both a value and a property, which doesn't really make sense. It's just one of the quirks in JS you have to learn to live with. You can verify this like so:

window.hasOwnProperty('undefined');//true
window.undefined;//undefined of course
window.hasOwnProperty('null');//false
typeof null;//object (really! But it is actually a primitive 
typeof undefined;//undefined

null is an object for historic reasons, but I'm not going to give you "The unabridged history of ECMAScript", Just thought you might like to know that.

What you have to keep in mind is how JS resolves variable names, and expressions. I've explained this many times, see this answer and all of the links at the bottom for details on the matter

Community
  • 1
  • 1
Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • Nit 1: `undefined in window` works because it is equivalent to `'undefined' in window` - it is the stringification of the property name that makes it work. That is, `undefined` (the value) is *not* a property, but `'undefined'` is. – user2864740 Jan 31 '14 at 08:46
  • Nit 2: `null` is a [*primitive* value](http://es5.github.io/#x4.3.2) and *not* an object. `typeof` is misleading here - just as it returns `"function"` for Function objects, but `"object"` for Array objects .. It is just how `typeof` works. – user2864740 Jan 31 '14 at 08:48
  • @user2864740: On both nits: I don't contradict/say otherwise. Or at least, I never meant to. I'll edit the stringification of `undefined` bit to be more clear, but I added `window.undefined` which sort of implies that undefined is stringified in the `a in window` case... On null being an `object`: I clearly stated that this is down to historic reasons, not because `null` is an object – Elias Van Ootegem Jan 31 '14 at 10:10
  • I've not said this answer was wrong (and indeed it got my positive vote), just throwing in some finer details - for those who are actually concerned with such :| – user2864740 Jan 31 '14 at 10:11
  • @user2864740: Didn't mean to come across all defensive, just wanted to clarify I didn't mean to say anything else. Took your comments to heart and edited my answer to avoid any confusion. – Elias Van Ootegem Jan 31 '14 at 10:13
2

When you say

"a" in window 

javascript looks for a property called a in the window object, and hence returns true.

For

a in window

a evaluates to undefined as noted by @Ootegem and hence returns true.

jacquard
  • 1,307
  • 1
  • 11
  • 16
  • Oh of course - `a in window` *evaluates* `a`. Duh! Thank you for the explanation. – flossfan Jan 31 '14 at 08:11
  • When `undefined` is used as a property name it is implicitly converted to a string - which happens to be `'undefined'`. Thus `undefined in window` is equivalent to `'undefined' in window`. – user2864740 Jan 31 '14 at 08:44