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
未定义的逻辑相当简单正确