Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling member function of number literal

Tags:

javascript

I'm trying to call literal functions, but I get weird behavior.

Consider this code which returns true.

   23 === (23) 

When I write try the following.

(23).toFixed(2) 

I get the expected result _23.00_ but when I try 23.toFixed(2) I get this error.

SyntaxError: Unexpected token ILLEGAL

How does JavaScript evaluate expressions that cannot understand this and why do I get this error?

like image 367
Behrad Farsi Avatar asked Sep 01 '13 06:09

Behrad Farsi


People also ask

How do you declare member function outside class?

Whenever the definition of a class member appears outside of the class declaration, the member name must be qualified by the class name using the :: (scope resolution) operator. The following example defines a member function outside of its class declaration.

What is the correct syntax for calling a member function?

Which is the correct syntax to call a member function using pointer? Explanation: The pointer should be mentioned followed by the arrow operator. Arrow operator is applicable only with the pointers. Then the function name should be mentioned that is to be called.

How is member function of a class defined?

A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.

How do you declare a member function in C++?

Member functions are operators and functions that are declared as members of a class. Member functions do not include operators and functions declared with the friend specifier. These are called friends of a class. You can declare a member function as static ; this is called a static member function.


1 Answers

The answers by Greg Hewgill and icktoofay are correct in all ways, however, I'd like to get down a bit, abstraction-wise: Let's see what's really happening according to the javascript specification.

Section 7.8.3 of the spec defines numeric literals. We can see the following:

DecimalLiteral ::     DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)     . DecimalDigits ExponentPart(opt)     DecimalIntegerLiteral ExponentPart(opt)  DecimalIntegerLiteral ::     0      NonZeroDigit DecimalDigits(opt) 

A DecimalLiteral, a number, is a bunch of decimal digits, possibly followed by a dot, which is possibly followed by other digits (all of which can be followed by an exponent, e12 for instance). In other words, 42. is legal and equal to 42 and 3e2 is equal to 300.

Note how if we have a dot, we either expect it to be followed by more digits/exponent, or be followed by nothing. However, and this is the important part, the dot is part of the number. Remember this as we move to look how the dot operator, obj.prop, is dealt with.

Section 11.2.1, Property Accessors describes the dot and bracket notation for member access:

MemberExpression . IdentifierName 

CallExpression is for function calls, which we don't care about. Notice how we're expecting a MemberExpression (which can be a DecimalLiteral - but don't take my word for it, look and see whether I'm right).

See that little dot? It's logical to jump forward and say "well, there's a dot in the scheme here...and there's a dot in 4.foo...so why is there an error?" Alas my hypothetical friend whom I use for these sentences, you forgot how the DecimalLiteral looks like! Let's go over two examples and see what happens.

42.foo ^ 

The caret represents the character we're on. So far, we're inside DecimalLiteral / DecimalIntegerLiteral / NonZeroDigit (that's quite a mouthful). Let's move to the next character:

42.foo  ^ 

Still part of the number, a perfectly valid DecimalDigit.

42.foo   ^ 

ok, so we're out of the DecimalIntegerLiteral part. Here's the same diagram on the scheme:

DecimalIntegerLiteral . DecimalDigits(opt) ExponentPart(opt)                       ^ 

So we're on a dot, which is a perfectly valid part of a number. Now we consume it, as part of the number, and move on:

42.foo    ^ 

f is neither part of DecimalDigits nor of ExponentPart, we're out of the number now. So...what now? What's that f? It's not part of anything. Maybe it's a property accessor? Let's take a look at the scheme:

MemberExpression . IdentifierName       ^ 

We're definitely on MemberExpression, but we don't have a dot which follows it - that dot is already part of the number. We've reached a syntactical error: we stop execution and throw it. Hopefully you don't live in a glass house.

Hopefully now you understand why 42..foo works. Once we're out of the MemberExpression, we face another dot:

              42..foo                  ^ MemberExpression . IdentifierName                  ^ 

Followed by a perfectly legal IdentifierName.

Of course, there're several other ways to separate the dot from the number. One way, as you showed, is to surround the literal in parentheses: (42).foo. When we've reached the parentheses end, we're out of the MemberExpression, and on the dot. Another way is to insert a space: 42 .foo, since a space can't be part of the number, and it's neutral for the parser, so it won't raise an error.

like image 158
Zirak Avatar answered Oct 11 '22 14:10

Zirak