我不明白为什么这两个JS表达式不相等
为了更好地使用JS,我正在尝试一些JavaScript表达式。这是我的最新发现:
{ a: y = 1 } = { b: 2 } // {b: 2}
{ a: 1 } = { b: 2 } // Uncaught SyntaxError: Unexpected token =
有人可以帮助我理解吗?
答案 0 :(得分:3)
首先,这不是destructuring assignments without declarations的正确语法。
使用不带声明的对象文字解构分配时,需要在赋值语句周围加上括号(...)。
{a,b} = {a:1,b:2}是无效的独立语法,因为左侧的{a,b}被认为是一个块,而不是对象文字。< / p>
您可以编写以下内容之一:
// assignment with declaration
const { a: y = 1 } = { b: 2 }
const { a: 1 } = { b: 2 }
// without declaration
({ a: y = 1 } = { b: 2 })
({ a: 1 } = { b: 2 })
const { a: y = 1 } = { b: 2 }
将创建一个值为y
的新变量1
。 a
不能是{ b: 2 }
中的destructured,而是default value为1。a
也将是assigned to a new variable名称y
。
({ a: 1 } = { b: 2 })
不起作用,因为a
无法解构并且没有默认值。因此,您得到SyntaxError: invalid destructuring target
。
destructuring assignment是expression。如果在浏览器控制台中键入{ a: y = 1 } = { b: 2 }
,则会得到SyntaxError: expected expression, got '='
,因此代码无法解释为表达式-而是将其视为block(零个或多个语句)。有一个解决方案-您可以使用括号来强制使用显式表达式上下文。这就是({ a: y = 1 } = { b: 2 })
起作用的原因。您还可以 在浏览器控制台中输入console.log({ a: y = 1 } = { b: 2 })
,因为引擎可以确定function参数为表达式。
也可以看看这个quote:
[...]与表达式语句有一个重叠:在那里,您有一些出现在语句上下文中的表达式。为了防止歧义,JavaScript语法禁止表达式语句以大括号或关键字function开头。
那么,如果要编写以这两个标记中的任何一个开头的表达式语句,该怎么办?您可以将其放在括号中,这不会改变其结果,但可以确保其出现在仅表达式的上下文中。
在控制台中输入{ a: y = 1 } = { b: 2 }
时,将得到以下输出:
SyntaxError: expected expression, got '='
{b: 2}
Du,为什么呢? Chrome / Node的输出表明该代码确实已被控制台评估为表达式,因为它的结果等于等号(quote)右侧的值{b:2
}:>
[...]从概念上讲,有两种类型的表达式:具有副作用(例如:那些为变量赋值的表达式)和在某种意义上可以评估并因此解析为值的表达式。
表达式x = 7是第一种类型的示例。该表达式使用=运算符将值7分配给变量x。该表达式本身的值为7。
如果您在Chrome / Node控制台中输入eval('{ a: y = 1 } = { b: 2 }')
,则会得到Uncaught SyntaxError: Unexpected token '='
,这是正确的行为! eval('var { a: y = 1 } = { b: 2 }')
照常工作。我认为,这是一个有力的信号,即控制台本身会积极尝试将代码解释为表达式,并且 V8引擎正常运行而不会出现错误。
答案 1 :(得分:1)
这取决于您如何运行。如果这个东西在顶层,如
{ a: 1 } = { b: 2 }
错误是“意外的=“,因为{a:1}
是一个块,而不是对象(例如,Differentiate a block from an object initializer)。
如果用作表达式
({ a: 1 } = { b: 2 })
错误(至少在V8中)是“无效的销毁分配目标”。
此:
let { a: 1 } = { b: 2 };
会产生“意外数字”,尽管与上面的错误相同:您不能有一个名为“ 1”的变量。
最后,如果您在控制台中运行此命令,结果通常是不可预测的,因为控制台会尝试“提供帮助”并使用评估后的代码做一些奇怪的事情。
答案 2 :(得分:1)
它们是不同的,因为在{ a: y } =
中,y
是可以分配给的值容器(并被解析,因为您编写的表达式被解析为解构表达式)。 1
是一个值,不能分配给它。因此,它不能构成有效的解构表达式。 { a: y = 1 } =
并不代表{ a: ( y = 1 ) } =
,而是y = 1; { a: y } =
。同样,它是特殊的解构语义,可能与操作员通常的意义背道而驰。混合功能性和命令性语言范式的危险:)