ReferenceError:赋值中的左侧无效

时间:2013-09-03 16:59:31

标签: javascript logic

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

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

当我输入参数

toss("rock","rock")

我收到此错误代码:

  

“ReferenceError:赋值中的左侧无效”

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

3 个答案:

答案 0 :(得分:46)

如果要比较类型,则必须使用==进行比较(甚至===。单个=用于分配。

if (one == 'rock' && two == 'rock') {
    console.log('Tie! Try again!');
}

答案 1 :(得分:5)

错误的常见原因:

  • 使用作业(=)代替平等(== / ===
  • 分配给函数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无法评估为可分配给的l值(在此特定情况下,它将是 of {{ 1}}为truthy)。

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

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

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

Assignment

  

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

Left-Hand-Side Expressions

解释IsStrictReference的

The Reference Specification Type

  

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

答案 2 :(得分:0)

使用eslint模块对我来说也是如此。 EsLinter会在第二条if语句中抛出Parsing error: Invalid left-hand side in assignment expression等待。

if (condition_one) {
  let result = await myFunction()
}

if (condition_two) {
  let result = await myFunction() // eslint parsing error
}

听起来很奇怪,但是此错误是要添加的;分号在等待发生的行尾。

if (condition_one) {
  let result = await myFunction();
}

if (condition_two) {
  let result = await myFunction();
}