JavaScript Syntax Nuances

If you learn a programming language it is unlikely that you will read the formal language specification that defines all the laws of the syntax. You may never read it at all. It is more useful to learn by example, or at least topic-by-topic. However, a mere ten years after writing my first few lines of JavaScript, I read the ECMAScript standard and it threw up some things I did not know.

There are many things that you can write in JavaScript that are perfectly valid syntax, but that you probably never will write. Here are a few that raised an eyebrow or two.

Comma Operator

What would you expect to see if you ran this code in your browser?

var test = [ 'a', 'b', 'c' ];
alert( test[ 0, 1, 2 ] );

You might expect it to be a syntax error, but in fact test[0,1,2] evaluates in this example to "c". The expressions ( 0, 1, and 2 ) are all evaluated, but only the final one can return the single value of the expression.

Similarly pointless constructs:

if( alert("Hello"), alert("World"), false ){
    alert("You will never see this");
}
var a = ( 1, 2, 3 ); // a will be set to 3

The “/” character

The syntax does not discriminate between operand types. For example, you can attempt to divide any expression by any other expression, even if it makes no sense to do so; such as:

['a'] / 2

This will evaluate to NaN, because the array’s value can never be a number, but it is perfectly valid syntax. The real point I’m getting to is that the following is an exception and will raise syntax error:

{ a:1 } / 2;

Why? Because the lexical analyser will expect "/" to be the start of a Regular Expression Literal, which it isn’t. It gets it ‘wrong’ in this case, because the "}" a is tricky so-and-so; it could either be the end of an expression, or the termination of a block statement. The lexical analyser is not a full syntax parser; it knows nothing of the full grammar of the language, and so it makes a choice based on some fairly weak rules.

The following IS valid, but it is not a division operation, it is just a pointless mess:

{ a:1 } / 2 /i;

undefined vs null

undefined is not a literal, or even a reserved word, whereas null is. undefined is a special built-in object, so if you were stupid enough, you could do this:

undefined = true;

This is allowed by the same token that allows you to foolishly do this:

Array = null;
var a = new Array();
// TypeError: Array is not a constructor