Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the rules for invoking functions on number literals in JS? [duplicate]

Tags:

javascript

Since I started working with JS, I've thought the only way to invoke a function on a number literal is to put it in expression position by wrapping it with parens, like so:

1.toString();
// SyntaxError: identifier starts immediately after numeric literal

(1).toString();
// "1"

Today, it occurred to me to try this:

0.1.toString();
// "0.1"

Why does this work? A pointer into the official spec would be great.

Edit Ambiguity was my first thought, but then decided that there's no ambiguity in 1.toString() either. It's deeper than I first thought, but I still think I'm right. Here's why:

Property names can begin with digits

var obj = { "1" : 1, "2" : 2 };

Property names that begin with digits can only be referenced with square brackets

obj.1;
// SyntaxError: Unexpected token ILLEGAL
obj['1'];
// 1

Also:

1['toString']();
// '1'

Therefore, 1. followed by any non-digit will always be a method call or property access, never a decimal number. Likewise, 1. followed by any digit will always be a decimal number, never a method call or property access.

like image 243
mwcz Avatar asked May 02 '12 16:05

mwcz


1 Answers

Once it's seen the first . in 0.1, then a subsequent . cannot be part of the number.

It's all about ambiguity.

edit — section 7.8.3 of the spec explicitly insists on this:

The source character immediately following a NumericLiteral must not be an IdentifierStart or DecimalDigit.

I'm not sure exactly what that's trying to prevent, but the JavaScript lexer is pretty gnarly, mostly thanks to the regex literal grammar and the need for a weird parser-lexer hack to deal with that.

like image 154
Pointy Avatar answered Sep 22 '22 00:09

Pointy