JavaScript中的链式赋值和循环引用

ant*_*129 6 javascript

请考虑以下陈述:

var foo = {n: 1};
foo.bar = foo = {n: 2};
Run Code Online (Sandbox Code Playgroud)

你能解释为什么foo.barundefined被代替foo

geo*_*org 12

执行赋值运算符时,JS首先计算左侧部分.所以这

foo.bar = foo = {n: 2};
Run Code Online (Sandbox Code Playgroud)

被解释为

  1. 评估foo.bar.这会返回一个引用{base: Object {n:1}, property:bar}.

  2. 然后评估第二个任务:

    2.1评估foo.这会返回一个引用{base:<scope>, property:foo}

    2.2.评估{n:2}.这会创建一个新对象.

    2.3投入价值: <scope>.foo = {n:2}

    2.4回归 {n:2}

  3. 把价值放到第一个参考:{n:1}.bar = {n:2}.这样运行正常,但旧对象{n:1}不再可访问,因为<scope>.foo已经引用了新对象

详情:http://ecma-international.org/ecma-262/5.1/#sec-11.13.1

如果您复制foo之前的版本,您会看到最左边的=实际修改旧对象:

var foo = {n:1};
var oldFoo = foo;

foo.bar = foo = {n: 2};

document.write(JSON.stringify(foo) + "<br>")
document.write(JSON.stringify(oldFoo) + "<br>")
Run Code Online (Sandbox Code Playgroud)