var obj = {
a: 1
};
obj.b = obj = {
c: 2
};
console.log(obj.b);//undefined
obj.b 为何输出undefined ?
var obj = {
a: 1
};
obj.b = obj = {
c: 2
};
console.log(obj.b);//undefined
obj.b 为何输出undefined ?
obj.b = obj = {c:2}
这句话可以理解成:先进行 obj = {c:2},再进行 obj.b = obj。
但这里是单语句,真正的赋值结果的保存是在语句执行完之后
所以这里,obj.b 还是在操作 {a:1},而 obj = {c:2} 则是让obj指向了一个新对象
执行之后,原对象变成 {a:1, b: {c:2}},但obj已经不指向它了,obj指向了{c:2}
所以 obj.b 当然就是undefined
var obj = {
a: 1
};
x = obj = {
c: 2
};
console.log(obj.b);//undefined
你把上面的 obj.b 改成 x 再想。
这个很容易理解啊,其实就考量的运算符优先级和GC。
下面我们深入浅出去探究这个问题,如果看不懂的,欢迎跟帖咨询。
我们把上面的代码改下:
var obj = {
a: 1
};
obj.b = obj = {
c: 2
};
此时能正确的输出2.
当连等的时候,会从右往左依次执行。
var obj = {
a: 1
};
假如此时obj
的对象地址为0x12341234
,当执行下面一句
obj={
c:2
};
时,obj
又重新申请了一块内存用于存放新的对象,0x12345678
。
此时,gc
会释放掉原来的对象内存即0x12341234
。
接下来
obj.b=obj;
注意,这两个obj
是不一样的,前一个obj的地址为0x12341234
,后一个为新申请的内存地址为0x12345678
。
然而前一个内存已经不存在了,对其操作会出错,当然,js的容错机制已经拦截了这个错误,并没有体现出来。也就是说,这是一个无意义的指令。
所以最后的结果是
Object {c: 2}
也就是说,最后的这个对象只有一个成员,就是c
。console.log(obj.b)
当然是未定义的。
断点测试。有图有真相:
个人认为,对于javascript,连续赋值
是这样的:a=b=c
等价于 a=b;b=c
这样也符合
赋值操作符 “=” 永远从等式的右边往左边赋值
补充一个图:
很多时候,chrome就是强大的工具,哈
10 回答11.3k 阅读
5 回答4.9k 阅读✓ 已解决
4 回答3.2k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
其实这个东西这么解释会清楚点:
根据上面,所以整个等式第一步是先添加一个
b
的地址,等式大概变成这个样子[obj.b的地址]=obj={c:2}
所以,变形后的等式运算时分为两步
obj={c:2}
,然后[obj.b的地址]=obj
。由于第一步的时候,
obj
已经指向新的地址,所以和[obj.b的地址]
中的obj
已经不是同一个。所以,第二步的时候,
[obj.b的地址]=obj
是把新的obj
赋值给原本obj.b的地址。所以才会出现
obj
输出{c:2}
的情况。更清晰一点,看看一个代码: