错误的常见原因:
- 使用赋值 (
=) 而不是相等 (==/===)
- 分配给函数
foo() = 42 的结果而不是传递参数 (foo(42))
- 只是缺少成员名称(即假设某些默认选择):
getFoo() = 42 而不是 getFoo().theAnswer = 42 或数组索引 getArray() = 42 而不是 getArray()[0]= 42
在这种特殊情况下,您想使用==(或更好的=== - What exactly is Type Coercion in Javascript?)来检查是否相等(如if(one === "rock" && two === "rock"),但您收到错误的实际原因更棘手。
错误原因是Operator precedence。特别是我们正在寻找&&(优先级6)和=(优先级3)。
让我们根据优先级在表达式中添加大括号 - && 高于 = 所以它首先执行类似于 3+4*5+6 和 3+(4*5)+6 的执行方式:
if(one= ("rock" && two) = "rock"){...
现在我们有了类似于a = b = 42 等多个赋值的表达式,由于从右到左的关联性,它被执行为a = (b = 42)。所以添加更多的大括号:
if(one= ( ("rock" && two) = "rock" ) ){...
最后我们遇到了实际问题:("rock" && two) 不能被评估为可以分配给的左值(在这种特殊情况下,它将是two 的 值 为@987654323 @)。
请注意,如果您使用大括号将每个“相等”周围的感知优先级与大括号匹配,则不会出错。显然,这也会产生与您预期不同的结果 - 由于@987654324 的行为,这两个变量的值和&& 两个字符串"rock" && "rock" 上的值都不同,导致"rock" (这反过来又是真实的) @:
if((one = "rock") && (two = "rock"))
{
// always executed, both one and two are set to "rock"
...
}
有关错误的更多详细信息以及可能发生的其他情况 - 请参阅规范:
Assignment
LeftHandSideExpression = 赋值表达式
...
如果以下条件都为真,则抛出 SyntaxError 异常:
...
IsStrictReference(lref) 为真
Left-Hand-Side Expressions
和The Reference Specification Type 解释 IsStrictReference:
... 函数调用被允许返回引用。这种可能性纯粹是为了宿主对象而被承认的。本规范定义的内置 ECMAScript 函数没有返回引用,也没有规定用户定义的函数返回引用...