JavaScript is an awesome language however it exhibits some quirks; this posts examines some of these fine odd aspects of JS; dive in, you’ll love it!
First, what do these 3 code snippets do?
3.toString();
void 0;
(3,4);
If your answers were ‘SyntaxError: Unexpected token ILLEGAL‘, undefined and 4; then give yourself a pat on the back! You nailed it. Now, lets find out why…
1. 3.toString() – Decimal Point or Number method?
This throws a SyntaxError because the code is confusing to the JavaScript Interpreter. The dot after the 3 is ambiguous – does it signify a decimal point or a method of the Number object?
JavaScript chooses to interpret it as a decimal number, it thus expects valid decimal digits after the dot – e.g. 3.0, 3.1, 3.999999999 etc. When it finds ‘toString’ instead of a digit; the interpreter goes KA-Boom! SyntaxError!!
Workarounds
Here are a couple of ways to fix this:
1. Wrap the decimal in parentheses – this forces it to be seen as a single expression; e.g. (3.).toString();.
2. Add a decimal digit after the dot – 3.1.toString(); this removes all ambiguity about the dots: the first is the decimal point while the second is a method from the Number object (after all, there can’t be two decimal points in a single number).
3. Use 3..toString(); this is less readable but works too. As explained above, 3. is a float while 3 is an integer; thus any dots appearing after 3. will definitely refer to a method of the Number object.
2. Void 0 – The Void Operator
This evaluates the expression that appears after it and always returns undefined. void 1, void 2 or void “blah” also work (any expression is fine) however the convention is to stick to void 0.
This can be used to ensure that undefined is always undefined (in JS land, clobbering window.undefined is fair game). Since the return value of the void operator is guaranteed to be undefined; functions like the one below are employed as safeguards. In fact a couple of JS libraries (e.g. underscore) use this technique quite often.
undefined = "defined"; //Gotcha!
function getUndefined() {
return void 0;
}
The void operator is also used in bookmarklets (bookmarks that allow you to do stuff by executing JavaScript) and while using the javascript:url coding style (which I assume no one uses…).
In these scenarios; returning a value will make the browser navigate to the returned value. Thus evaluating the expression in a void call kills two birds with a stone – you get to evaluate your expression while still preventing the browser from navigating away.
3. (3,4) – The Comma Operator
The comma operator takes a series of expressions, evaluates all of them from left to right and returns the result of the last expression. This can be leveraged in evaluating multiple scenarios where only a single expression is expected. So you can do something like 2,3,4,5,”wow… this is valid JavaScript!”, 9 and the result will be 9! Impressive huh?
The comma operator should not be confused with the comma separator in variable declarations; that comma separator allows the combination of multiple var declarations into a single one.
The comma operator only occurs within expressions as shown below:
var x = 2,3,4,5,"valid JavaScript!",9
// SyntaxError: Unexpected number
// Wrap in expression
var x = (2,3,4,5,"valid JavaScript!",9)
console.log(x);
//9
If you are pedantic then you find it pleasing to know that the comma operator in JavaScript was taken from the C comma operator…
Extra Bonus
The typeof operator is a unary operator but calling it like a function (i.e. typeof(3) ) seems to work perfectly. Strange?
Here is what I believe happens:
typeof(3) -> typeof (3) -> typeof 3 -> Number
The same reasoning would apply to the void operator; and that’s why you have usages like void (0).
There you go! Now go spread some JavaScript love!! :D
Nice one! Keep it up. I’m also getting up to speed on JavaScript and I like your energy. Just a quick word about typeof(). It can spring up surprises, so you want to watch how you use it. For example, typeof(null) returns ‘object’. A similar thing happens with typeof([1]). So for primitive types, typof() is fine. For non-primitive types, you want to use utility methods like isArray, isFunction, etc.
LikeLike
Thanks for the feedback medat!
Yes the return value of the typeof operator is another quirky area of JS; you are right it does have all sorts of issues.
I was actually referring to the fact that typeof is an operator and not a function; theoretically calling it as a method should not work but it does when you add a value between braces.
typeof() -> SyntaxError
typeof(3) -> “number”
Thanks for the feedback!
LikeLike