Valid javascript object property names

I'm trying to work out what is considered valid for the property name of a javascript object. For example

var b = {}
b['-^colour'] = "blue";     // Works fine in Firefox, Chrome, Safari
b['colour'] = "green";      // Ditto
alert(b['-^colour']);       // Ditto
alert(b.colour);            // Ditto
for(prop in b) alert(prop); // Ditto
//alert(b.-^colour);     // Fails (expected)

This post details valid javascript variable names, and '-^colour' is clearly not valid (as a variable name). Does the same apply to object property names? Looking at the above I'm trying to work out if

  1. b['-^colour'] is invalid, but works in all browsers by quirk, and I shouldn't trust it to work going forward

  2. b['-^colour'] is completely valid, but it's just of a form that can only be accessed in this manner - (it's supported so Objects can be used as maps perhaps?)

  3. Something else

As an aside, a global variable in javascript might be declared at the top level as

var abc = 0;

but could also be created (as I understand it) with

window['abc'] = 0;

the following works in all the above browsers

window['@£$%'] = "bling!";
alert(window['@£$%']);

Is this valid? It seems to contradict the variable naming rules - or am I not declaring a variable there? What's the difference between a variable and an object property name?


Solution 1:

Yes, objects can be used as maps, and any string can be a property name. As you've discovered, some properties can only be accessed using the bracket syntax.

window['abc']

is accessing a property. It is not a variable, even though it refers to the same value (at the global level) as:

abc

Solution 2:

Object property naming rules and variable naming rules are separate. The standard only "reserves" a handful of property names (such as prototype and constructor, IIRC), but other than those, any string goes.

Except when the execution environment (i.e. the browser) decides to add more magic properties, of course. (I hear setting __proto__ breaks some things in quite weird ways)

Solution 3:

  1. Every time you create a global variable you create in fact a new member of a global object (which is window in browser environment, global in Node.js, etc.). This is why window.x is exactly the same like (global) var x, this.x or just x.

  2. Understanding JavaScript object like a map is quite right, because: a) you can add a new element dynamically - at any moment; b) the element can have any name - also including special characters, c) you can try to access a non-existing element of an object/map and it is not an error, d) you can remove an element from an object.

  3. If you like to access object members with standard dot notation (eg. a.x) you are not allowed to use any special characters different than _ or $; also the name cannot start from a number. For all other cases you are forced to use square brackets and quotation marks to access object elements.