多重分配混乱 [英] Multiple assignment confusion

查看:122
本文介绍了多重分配混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道赋值运算符是正确的关联.

I understand that the assignment operator is right associative.

因此,例如x = y = z = 2等效于(x = (y = (z = 2)))

在这种情况下,我尝试了以下操作:

That being the case, I tried the following:

foo.x = foo = {a:1}

我希望对象foo将使用值{a:1}创建,然后属性x将在foo上创建,而该属性只是对foo对象的引用.

I expected that the object foo would be created with value {a:1} and then the property x will be created on foo which will just be a reference to the foo object.

(如果我将多重赋值语句分成两个独立的语句foo = {a:1};foo.x = foo;,实际上会发生这种情况)

(This is actually what happens if I was to separate the multiple assignment statement into two separate statements foo = {a:1};foo.x = foo; )

结果实际上是:

ReferenceError:未定义foo(...)

ReferenceError: foo is not defined(…)

因此,我尝试了以下操作:

So then I tried the following:

var foo = {};
foo.x = foo = {a:1};

现在我不再遇到异常,但是foo.x未定义!

Now I don't get the exception anymore but foo.x is undefined!

为什么作业无法按预期工作?


免责声明:重复"问题似乎与我要问的完全不同,因为存在一个问题,即分配中创建的变量是全局变量,与创建的变量相对应使用var关键字.这不是这里的问题.

Why is the assignment not working as I expected?


Disclaimer: The 'duplicate' question seems to be very different to the one that I'm asking, as the issue there is that the variables that were created in the assignment were global, as apposed to variables created with the var keyword. That's not the issue here.

推荐答案

关联性评估顺序之间存在重要区别.

There's an important difference between associativity and order of evaluation.

在JavaScript中,即使赋值运算符 groups 从右到左,在执行实际赋值之前,操作数也是从左到右评估的( do 从右到左).考虑以下示例:

In JavaScript, even though the assignment operator groups right to left, the operands are evaluated left to right before the actual assignments are performed (which do occur right to left). Consider this example:

var a = {};
var b = {};
var c = a;

c.x = (function() { c = b; return 1; })();

变量c最初引用a,但是赋值的右侧将c设置为b. a.xb.x被分配了哪个属性?答案为a.x,因为当c仍引用a时,首先评估左侧.

The variable c initially references a, but the right-hand side of the assignment sets c to b. Which property gets assigned, a.x or b.x? The answer is a.x because the left-hand side is evaluated first, when c still references a.

通常,表达式x = y的计算方式如下:

In general, the expression x = y is evaluated as follows:

  1. 评估x并记住结果.
  2. 评估y并记住结果.
  3. 将步骤2的结果分配给步骤1的结果(并返回前者作为表达式x = y的结果).
  1. Evaluate x and remember the result.
  2. Evaluate y and remember the result.
  3. Assign the result from step 2 to the result of step 1 (and return the former as the result of the expression x = y).

x = (y = z)所述,多次分配会发生什么?递归!

What happens with multiple assignments, as in x = (y = z)? Recurse!

  1. 评估x并记住结果.
  2. 评估y = z并记住结果.去做这个:
  1. Evaluate x and remember the result.
  2. Evaluate y = z and remember the result. To do this:
  1. 评估y并记住结果.
  2. 评估z并记住结果.
  3. 将步骤2.2中的结果分配给步骤2.1中的结果(并返回前者作为表达式y = z的结果).
  1. Evaluate y and remember the result.
  2. Evaluate z and remember the result.
  3. Assign the result from step 2.2 to the result of step 2.1 (and return the former as the result of the expression y = z).

  • 将步骤2的结果分配给步骤1的结果(并返回前者作为表达式x = (y = z)的结果).
  • Assign the result from step 2 to the result of step 1 (and return the former as the result of the expression x = (y = z)).
  • 现在让我们看一下您的示例,对其进行稍加修改:

    Now let's look at your example, slightly edited:

    var foo = {};
    var bar = foo;         // save a reference to foo
    foo.x = (foo = {a:1}); // add parentheses for clarity
    

    foo.x是在将foo分配给{a:1}之前进行评估的,因此,会将x属性添加到原始的{}对象中(可以通过检查bar进行验证).

    foo.x is evaluated before foo gets assigned to {a:1}, so the x property gets added to the original {} object (which you can verify by examining bar).

    这篇关于多重分配混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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