4

This JavaScript snippet

var x = window.foo;
window.x = null;
alert( window.bar === undefined );

alerts "true".

However, this snippet

var x = window.foo;
window[x] = null;
alert( window.bar === undefined );

alerts "false".

What is going on here?

(I am running this code in the latest Chrome browser inside a HTML page with no other JavaScript code in it.)

Update

As @elusive cleverly summed up in his comment below, I mistakingly assumed that window.x and window[x] are equivalent. That is not correct. window.x is equivalent to window["x"].

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385

2 Answers2

3

The behavior that you are experiencing is because the undefined property of the Global object, is mutable on any ECMAScript 3 based implementation. (latest Chrome versions are implementing ES5, but this behavior is still present).

Let's examine the second snippet:

var x = window.foo;
window[x] = null;
alert( window.bar === undefined );

The x variable will hold the undefined value, since the foo property does not exist.

By assigning window[x] = null, you are overriding the value of the undefined property:

window[x] = null; // is equivalent to
window['undefined'] = null; // or
window.undefined = null; //

(In your first snippet, when you assign window.x = null, you are creating a property named "x" on the window object.)

Therefore (in your second snippet), the undefined property will hold null, and window.bar will produce undefined:

alert( window.bar === undefined ); // false
alert( undefined  === null ); // false

The undefined property was not specified as { ReadOnly } on ECMAScript 3, (along with his friends NaN, Infinity).

This has changed in ECMAScript 5, those properties are described as non-writables.

Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
  • @CMS Isn't the `undefined` global property mutable on any browser, not just Chrome? – Šime Vidas Nov 20 '10 at 20:24
  • @Šime, it *should* be mutable on any *ES3-based implementation*. From the latest browser versions that I have tested (Firefox, WebKit, IE9, Chrome), Chrome is the only one that still has `undefined` as writable, even on Chrome 9.0.583.0. – Christian C. Salvadó Nov 20 '10 at 20:33
  • @CMS These are not the results that I'm getting. The latest versions of Chrome, Firefox and Opera allow me to change the value of the `undefined` global property. Only IE9 beta and Safari don't allow it. – Šime Vidas Nov 20 '10 at 20:38
  • FWIW, jQuery is wrapped in `(function(window, undefined) { ... })(window)`, which ensures that `undefined` actually does have its correct value. – PleaseStand Nov 20 '10 at 20:41
  • @Šime by *latest versions* I meant **nightly builds**, *Firefox 4Beta8 Pre*, *Chrome 9.0.583.0*, *WebKit r72284*, etc... they do implement a lot of ES5, Firefox and Webkit are finishing strict-mode support :) – Christian C. Salvadó Nov 20 '10 at 20:42
  • @CMS Aha, those latest builds implement ES5 and therefore don't allow `undefined` to be changed. However, it is strange that Chrome 9 does allow it. Hey, can you do me a favor? Can you go to http://kangax.github.com/es5-compat-table/strict-mode/ in Chrome 9 and check out how it handles the strict mode rules. I would love to know that :) – Šime Vidas Nov 20 '10 at 20:50
  • @Šime, Chrome 9 doesn't implement strict mode **at all**, just like IE9... too bad, all red :(. If you want to play with strict mode, get the latest WebKit and Firefox :) – Christian C. Salvadó Nov 20 '10 at 21:04
1
var x = window.foo;  // set the local variable x to the contents of window.foo
window.x = null; // set property x on window to null

Here you're directly setting the propery x to null.

var x = window.foo; // set the local variable x to the contents of window.foo
window[x] = null; // set they key with the value of x to null

Here you're setting a property by using it as a key on the window object. Which key is that? Well that depends on the value of x, if x is bar you will effectively do window.bar = null if x is blub you'll do window.blub = null.

For more information on this you should head over to MDC:
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Member_Operators

Ivo Wetzel
  • 46,459
  • 16
  • 98
  • 112