问题
> "[object Number]" === Object.prototype.toString.call(1) // #1
< true
> "[object Number]" === {}.toString.call(1) // #2
< true
> {}.toString.call(1) === "[object Number]" // #3
< SyntaxError: Unexpected token '.'
> ({}).toString.call(1) === "[object Number]" // #4
< true
> {}.toString.call(1) // #5
< SyntaxError: Unexpected token '.'
> !{}.toString.call(1) // #6
< false
> test = {}.toString.call(1) // #7
< "[object Number]"
As you can see from the sample, #2 and #3 are almost identical except that the they have the left and right side exchanged. #2 works fine but #3 gives a syntax error. To get #3 to work, a pair of parentheses is required. Additionally, from #5-7 we can see that as long as {}
is not at the left most, it works fine.
But why?
回答1:
In #1, when it finds rvalue
and an operator ===
, javascript considers that the lvalue
could be a value or an expression.
In #2, same as #1. hence {}
is considered as an object literal
In #3, since javascript evaluates the statement from right to left, the {}
is considered just as a curly brace but not an object literal. hence #3 is not working because you won't be getting toString
function on curly braces.
In #4, when you enclose {}
within ()
grouping operator, javascript thinks it is an expression. hence #4 works because {}
is evaluated as an object literal and toString
be available.
In #5, same as #3. javascript thinks that {}
as just a brace since there is not expressions or with it.
In #6, same as #4. there is an expression !
. hence is evaluated as an object
In #7, same as #4. there is an assignment operator, hence is evaluated as an expression.
来源:https://stackoverflow.com/questions/39953621/syntax-error-when-directly-access-attribute-on-empty-object