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

JavaScript中的链式赋值和循环引用,javascript,Javascript,考虑以下陈述: var foo = {n: 1}; foo.bar = foo = {n: 2}; 您能解释一下为什么foo.bar是未定义的而不是foo?您更改了foo引用的对象。{n:2}中没有条。你期望什么?因此,当foo.bar的赋值发生时,foo的引用已“填写”。这使它成为原始对象 让我们稍微扩展一下代码,让它更清晰 var foo1, foo2; foo1 = foo2 = {n:1}; foo1 === foo2; // true foo1.bar = foo1 = {n:2}

考虑以下陈述:

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

您能解释一下为什么
foo.bar
未定义的
而不是
foo

您更改了
foo
引用的对象。
{n:2}
中没有
。你期望什么?

因此,当
foo.bar
的赋值发生时,
foo
的引用已“填写”。这使它成为原始对象

让我们稍微扩展一下代码,让它更清晰

var foo1, foo2;
foo1 = foo2 = {n:1};
foo1 === foo2; // true
foo1.bar = foo1 = {n:2}
foo1.bar === foo2; // false
foo1 === foo2; // false

这里有两个物体在起作用。一个会有酒吧,另一个不会。为了说明这一点,我将把原始对象存储在另一个变量中进行比较

var foo = {n: 1};
var orig = foo;
foo.bar = foo = {n: 2};
console.log(foo, orig); // {n:2}, {n:1, bar: {n:2}}

在执行
foo.bar
行之前,
foo
仍包含原始对象,因此原始对象的bar属性将设置为新对象。

执行赋值运算符时,JS首先计算左部分。那么这个

foo.bar = foo = {n: 2};
被解释为

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

  • 然后评估第二项作业:

    2.1评估
    foo
    。这将返回一个引用
    {base:,property:foo}

    2.2。eval
    {n:2}
    。这将创建一个新对象

    2.3输入值:
    .foo={n:2}

    2.4返回
    {n:2}

  • 将值放入第一个引用:
    {n:1}.bar={n:2}
    。这运行正常,但是旧对象
    {n:1}
    不再可访问,因为
    .foo
    已经引用了新对象

  • 详情:

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

    var foo={n:1};
    var oldFoo=foo;
    foo.bar=foo={n:2};
    document.write(JSON.stringify(foo)+“
    ”)
    document.write(JSON.stringify(oldFoo)+“
    原始对象
    foo
    拥有它,而不是新对象。如果您拥有
    foo.bar=foo={bar:2}
    ?那行得通。@不,不行
    foo.bar===2
    ,而不是
    {n:1}
    foo
    )@DanielA.White你能详细解释一下吗?@Mathletics它至少能给你一个明确的答案。这个问题确实存在<代码>栏
    不是foo的一部分。为什么
    foo.bar
    未定义的逻辑相当简单正确