ReferenceError:赋值中的左侧无效

Kev*_*vin 25 javascript logic

我的摇滚纸剪刀游戏(称为折腾)的代码如下:

var toss = function (one,two) {
    if(one = "rock" && two = "rock") {
        console.log("Tie! Try again!");
    }
    // more similar conditions with `else if`
};
Run Code Online (Sandbox Code Playgroud)

当我输入参数

toss("rock","rock")
Run Code Online (Sandbox Code Playgroud)

我收到此错误代码:

"ReferenceError:赋值中的左侧无效"

怎么解决?此错误意味着什么以及发生此错误时的其他情况?

Jos*_*ber 48

您必须使用==比较(或者甚至===,如果您想比较类型).单个=用于分配.

if (one == 'rock' && two == 'rock') {
    console.log('Tie! Try again!');
}
Run Code Online (Sandbox Code Playgroud)

  • 为了澄清一下, == 和 === 之间有什么区别? (2认同)

Ale*_*kov 5

错误的常见原因:

  • 使用赋值(=)而不是相等(==/ ===)
  • 分配给函数的结果foo() = 42而不是传递参数(foo(42))
  • 只是缺少成员名称(即假设一些默认选择):getFoo() = 42而不是getFoo().theAnswer = 42或数组索引getArray() = 42而不是getArray()[0]= 42

在这种特殊情况下,你想使用==(或者更好===- Javascript中的Type Coercion究竟是什么?)来检查是否相等(比如if(one === "rock" && two === "rock"),但是你得到错误的实际原因是棘手的.

错误的原因是运算符优先级.特别是我们正在寻找&&(优先级6)和=(优先级3).

让我们根据优先级放在括号中的表达- &&高于=所以它首先执行一个类似的会怎么做3+4*5+63+(4*5)+6:

 if(one= ("rock" && two) = "rock"){...
Run Code Online (Sandbox Code Playgroud)

现在我们有类似于多个赋值的表达式,例如a = b = 42由于从右到左的关联性执行a = (b = 42).所以添加更多大括号:

 if(one= (  ("rock" && two) = "rock" )  ){...
Run Code Online (Sandbox Code Playgroud)

最后,我们到达实际的问题:("rock" && two)无法进行评估,以可分配给(在这将是这种特殊情况下的L-value twotruthy).

请注意,如果您使用大括号来匹配围绕每个"相等"的感知优先级与大括号,则不会出现错误.显然,这也会产生与你期望的结果不同的结果 - 改变两个变量的值,而不是由于logial &&的行为导致&&两个字符串"rock" && "rock"导致"rock"(这反过来是真实的):

if((one = "rock") && (two = "rock"))
{
   // always executed, both one and two are set to "rock"
   ...
}
Run Code Online (Sandbox Code Playgroud)

有关错误的更多详细信息以及可能发生的其他情况 - 请参阅规范:

分配

LeftHandSideExpression = AssignmentExpression
...
如果以下条件都为真,则抛出一个SyntaxError异常:
...
IsStrictReference(lref)为true

左手表达式

和解释IsStrictReference 的参考规范类型:

...允许函数调用返回引用.纯粹为了宿主对象而承认这种可能性.此规范未定义的内置ECMAScript函数返回引用,并且没有为用户定义的函数提供返回引用的规定...