为什么不能像 {}.toString() 这样的对象文字调用 toString() 方法导致错误?
why can't object literal call toString() method like {}.toString() cause error?
当对象字面量调用toString()
方法时,如{}.toString()
会导致语法错误,但是当数组字面量调用toString()
时就可以了。当我将对象字面量赋值给一个变量时,那么当它调用 toString()
方法时就可以了。为什么?例如:
var o = {};
o.toString(); // OK
{}.toString();
// > Uncaught SyntaxError: Unexpected token .
[1, 2, 3].toString(); // OK
谢谢!
这是因为 {}
首先被视为有效块,而不是该上下文中的文字。
简单来说 - 考虑该行是从左到右解释的,遇到 {
并且因此预计一个块已经开始。当块结束时,它遇到 .
并且那里不允许该标识符。
如果您使用 ({}).toString()
就可以了。
这是因为该行以 (
开头,因此需要一个表达式,它正确地将 {}
识别为一个被计算为空对象的表达式,因此为 '.toString()`是允许的。
如果 {}
用于其他上下文 - 例如在您的示例中 o = {}
this 被正确解释为一个空对象,因为它位于赋值的右侧(在 =
之后)。
请注意,在 ES6 中有一种类似但更多 common/practical 的情况,理解这一点很重要 - 在单行箭头函数中返回对象时,例如
[1,2,3,4].map(val => { v: val, isOdd: v % 2 === 1 }) // ERROR
[1,2,3,4].map(val => ({ v: val, isOdd: v % 2 === 1 })) // OK
当对象字面量调用toString()
方法时,如{}.toString()
会导致语法错误,但是当数组字面量调用toString()
时就可以了。当我将对象字面量赋值给一个变量时,那么当它调用 toString()
方法时就可以了。为什么?例如:
var o = {};
o.toString(); // OK
{}.toString();
// > Uncaught SyntaxError: Unexpected token .
[1, 2, 3].toString(); // OK
谢谢!
这是因为 {}
首先被视为有效块,而不是该上下文中的文字。
简单来说 - 考虑该行是从左到右解释的,遇到 {
并且因此预计一个块已经开始。当块结束时,它遇到 .
并且那里不允许该标识符。
如果您使用 ({}).toString()
就可以了。
这是因为该行以 (
开头,因此需要一个表达式,它正确地将 {}
识别为一个被计算为空对象的表达式,因此为 '.toString()`是允许的。
如果 {}
用于其他上下文 - 例如在您的示例中 o = {}
this 被正确解释为一个空对象,因为它位于赋值的右侧(在 =
之后)。
请注意,在 ES6 中有一种类似但更多 common/practical 的情况,理解这一点很重要 - 在单行箭头函数中返回对象时,例如
[1,2,3,4].map(val => { v: val, isOdd: v % 2 === 1 }) // ERROR
[1,2,3,4].map(val => ({ v: val, isOdd: v % 2 === 1 })) // OK