为什么这是无效的左手边? [英] Why is this an invalid assignment left hand side?

查看:64
本文介绍了为什么这是无效的左手边?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我要执行以下操作:

Why can I do the following operations:

var b1, b2;

b1 = b2 = true;

document.write(b1," ", b2);
document.write("<br>");

b1 = !b2;

document.write(b1," ", b2);
document.write("<br>");

b1 = b2 = !true;

document.write(b1," ", b2);

但是,当我尝试以下操作时,我收到了ReferenceError: invalid assignment left-hand side吗?

Yet when I try the following operation I recieve a ReferenceError: invalid assignment left-hand side ?

var b1, b2;

b1 = !b2 = true;

document.write(b1," ", b2);

很明显,我不能这样做,但是我找不到为什么不能这样做的解释. MDN开发人员指南,用于错误状态:

It's obvious that I can't do this, but I can't find an explanation as to why I can't. The MDN developer guide for the error states:

某处发生了意外的任务.例如,这可能是由于赋值运算符和比较运算符不匹配所致.当单个"="符号为变量分配值时,"=="或"==="运算符会比较一个值.

There was an unexpected assignment somewhere. This might be due to a mismatch of a assignment operator and a comparison operator, for example. While a single "=" sign assigns a value to a variable, the "==" or "===" operators compare a value.

所有的赋值运算符都如经证明的那样单独工作,那么为什么不能将其合并为单个运算/链式赋值呢?

All of the assignment operators work individually as proven, so why can't this be combined into a singular operation / chained assignment?

推荐答案

当您尝试执行此操作时:

When you try to do this:

var b1, b2;

b1 = !b2 = true;

document.write(b1, " ", b2);

因为它们在功能上是等效的,您基本上是在这样做:

Because they are functionally equivalent you are basically doing:

var b1, b2;

!b2 = true;
b1 = true; //just the value of b2, not b2 itself

document.write(b1, " ", b2);

在行!b2 = true中,您试图将一个计算结果为值(左侧)的表达式分配给一个值-完全没有意义.这样想吧:

In the line !b2 = true, you are trying to assign an expression that evaluates to a value (the left side) to a value - that makes absolutely no sense. Think about it this way:

  • !b2被分配给true. !b2是一个表达式,并且被评估为布尔值 value ,而不是变量.
  • 这类似于执行1 + 1 = 2.由于1 + 1的值是 ,因此您不能将其分配给另一个值2.您必须为变量分配一个值,因为按值分配在语义和逻辑上都是无效的.
  • 考虑上述问题的另一种方法是实现这一点:1 + 1是一个值. 2是一个值.您无法将值分配给值,因为该值已具有值.诸如2的常量的值为2,无法更改.如果我们尝试1 - 1 = 2怎么办? 0,一个常量和值,不能为2,因为它是一个常量.
  • !b2 is being assigned to true. !b2 is an expression and is evaluated to a boolean value, not variable.
  • This would be analogous to doing 1 + 1 = 2. Since 1 + 1 is evaluated to a value, you can't assign that to 2, another value. You must assign a value to variable, as value-to-value assignment is semantically and logically invalid.
  • Another way to think about the above is to realize this: 1 + 1 is a value. 2 is a value. You cannot assign a value to a value, as that value already has a value. A constant such as 2 has value 2, it cannot be changed. What if we tried 1 - 1 = 2? 0, a constant and value, cannot be 2, because it is a constant.

因此,将值分配给值在语义和逻辑上都是无效的.您不能像将false分配给true一样将0分配给2.

Thus, it is semantically and logically invalid to assign a value to a value. You cannot assign 0 to 2 just as you can't assign false to true.

如果您想更好地理解语法和语义,以及为什么要抛出ReferenceError,则可以深入研究

If you want to understand the syntax and semantics better, and why this throws a ReferenceError, you can delve into the ECMAScript® 2015 Language Specification. Per the specification:

第12.14.1节 -赋值运算符-静态语义:早期错误

Section 12.14.1 - Assignment Operators - Static Semantics: Early Errors

AssignmentExpression : LeftHandSideExpression = AssignmentExpression

  • 这是早期的参考如果 LeftHandSideExpression 既不是 ObjectLiteral 也不是 ArrayLiteral LeftHandSideExpressionIsValidSimpleAssignmentTarget ,则错误em>是错误的.
  • It is an early Reference Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.

IsValidSimpleAssignmentTarget所在的位置:

第12.14节.3 -赋值运算符-静态语义:IsValidSimpleAssignmentTarget

Section 12.14.3 - Assignment Operators - Static Semantics: IsValidSimpleAssignmentTarget

AssignmentExpression :
  YieldExpression
  ArrowFunction
  LeftHandSideExpression = AssignmentExpression
  LeftHandSideExpression AssignmentOperator AssignmentExpression

1.返回false.

1. Return false.

现在回头看看您的代码:b1 = !b2 = true. b1 = !b2很好,因为它是 LeftHandSideExpression = AssignmentExpression ,因此对于IsValidSimpleAssignmentTarget返回true.当我们检查!b2 = true时会出现问题.如果我们看一下 LeftHandSideExpression 的定义:

Now look back at your code: b1 = !b2 = true. b1 = !b2 is fine because it is LeftHandSideExpression = AssignmentExpression, thus returning true for IsValidSimpleAssignmentTarget. The problem arises when we check !b2 = true. If we look at the definition of LeftHandSideExpression:

第12.3节 -左手表情

语法

LeftHandSideExpression :
  NewExpression
  CallExpression

(您可以在上面的规范链接中查看 NewExpression CallExpression 的定义)

(You can view the definitions of NewExpression and CallExpression in the specification link above)

您会看到!b2 = true不是有效的 AssignmentExpression ,因为它不符合条件 LeftHandSideExpression = AssignmentExpression .这是因为!b2不是有效的 LeftHandSideExpression ,也不是 ObjectLiteral 也不是 ArrayLiteral ,因此IsValidSimpleAssignmentTarget返回false,并抛出ReferenceError.请注意,该错误是 早期错误,这意味着它会在执行任何代码之前抛出,如

You can see that !b2 = true is not a valid AssignmentExpression, as it does not fit the criteria LeftHandSideExpression = AssignmentExpression. This is because !b2 is not a valid LeftHandSideExpression, also not an ObjectLiteral nor ArrayLiteral, thus IsValidSimpleAssignmentTarget returns false, throwing the ReferenceError. Note that the error is an early error, meaning it is thrown before any code is executed, as noted in @Bergi's comment.

您可以通过执行以下任一操作来解决此问题,具体取决于所需的结果:

You can combat this by doing either of the following, depending on your desired outcome:

b1 = !(b2 = true);

使用括号时,括号内的优先级高于外部.这样,就分配了b2,并且由于它是true,因此括号内的值将为true.接下来,它等效于:

With parentheses, inside the parentheses takes precedence over outside. That way, b2 is assigned, and since it is true, inside the parentheses evaluates to true. Next, it's equivalent to:

b1 = !(true);

如上所述,括号内的

As被评估为true. b1将与b2相反,而b2将是true.

As inside the parentheses is evaluated to true as mentioned above. b1 will be the opposite of b2 as expected, and b2 will be true.

如果您希望b1true,而b2false,则重新组织语句,如下所示:

If you wanted b1 to be true and b2 to be false, restructure the statement like this:

b2 = !(b1 = true);

这样,它与上面的完全相反,给出了b1 = trueb2 = false.

This way, it's the exact opposite of the above, giving b1 = true, and b2 = false.

正如注释中提到的@Bergi一样,b1被分配了正确的操作数,在这种情况下,true被分配了正确的操作数,而不是!b2.

As @Bergi mentioned in the comments, b1 is assigned the right operand, true in this case, not !b2.

尽管大多数浏览器目前不支持ECMAScript 6(2015)的所有功能,而是使用

Although most browsers currently do not support all features of ECMAScript 6 (2015), and instead use ECMAScript 5.1 (2011), the specification is the same for both versions. All definitions are the same, and thus the explanation is still valid.

这篇关于为什么这是无效的左手边?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆