当前位置:  开发笔记 > 编程语言 > 正文

多项任务混淆

如何解决《多项任务混淆》经验,为你挑选了1个好方法。

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

所以例如 x = y = z = 2相当于(x = (y = (z = 2)))

既然如此,我尝试了以下方法:

foo.x = foo = {a:1}

我期望foo使用value创建对象{a:1},然后x将创建属性,该属性foo将只是foo对象的引用.

(实际上,如果我要将多个赋值语句分成两个单独的语句,会发生什么foo = {a:1};foo.x = foo;)

结果实际上是:

ReferenceError:未定义foo(...)

那么我尝试了以下内容:

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

现在我不再得到例外但是foo.x未定义!

为什么作业不按我的预期工作?


免责声明:"重复"问题似乎与我提出的问题非常不同,因为问题在于赋值中创建的变量是全局的,与使用var关键字创建的变量相关联.这不是问题所在.



1> Michael Liu..:

关联性评估顺序之间存在重要差异.

在JavaScript中,即使赋值操作符从右到左的操作数进行评价左至右分别是执行实际任务之前(这发生从右到左).考虑这个例子:

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

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

变量c最初引用a,但赋值的右侧设置cb.分配了哪个属性,a.x或者b.x?答案是a.x因为在c仍然引用的情况下,首先评估左侧a.

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

    评估x并记住结果.

    评估y并记住结果.

    将步骤2的结果分配给步骤1的结果(并将前者作为表达式的结果返回x = y).

多项任务会发生什么情况,如x = (y = z)?递归!

    评估x并记住结果.

    评估y = z并记住结果.去做这个:

      评估y并记住结果.

      评估z并记住结果.

      将步骤2.2的结果分配给步骤2.1的结果(并将前者作为表达式的结果返回y = z).

    将步骤2的结果分配给步骤1的结果(并将前者作为表达式的结果返回x = (y = z)).

现在让我们看看你的例子,稍加编辑:

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

foo.xfoo被分配之前进行评估{a:1},因此该x属性被添加到原始{}对象(您可以通过检查来验证bar).

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有