【问题标题】:ReferenceError: Invalid left-hand side in assignmentReferenceError:分配中的左侧无效
【发布时间】:2013-09-07 00:08:30
【问题描述】:

我的剪刀石头布游戏代码如下:

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: 赋值左侧无效”

如何解决?这个错误是什么意思,还有什么其他情况会发生这个错误?

【问题讨论】:

  • 三个“领带”案例可以简化为一个if( one == two)

标签: javascript logic


【解决方案1】:

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

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

【讨论】:

【解决方案2】:

错误的常见原因:

  • 使用赋值 (=) 而不是相等 (==/===)
  • 分配给函数 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+63+(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 函数没有返回引用,也没有规定用户定义的函数返回引用...

【讨论】:

【解决方案3】:

eslint 模块也发生在我身上。 EsLinter 在第二个 if 语句中抛出 Parsing error: Invalid left-hand side in assignment expression for await。

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();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-02
    • 2018-06-10
    • 2017-01-08
    • 1970-01-01
    • 2016-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多