扫码关注官方订阅号
var obj = { a: 1 }; obj.b = obj = { c: 2 }; console.log(obj.b);//undefined
obj.b 为何输出undefined ?
ringa_lee
其实这个东西这么解释会清楚点:
.的优先级是高于=的,所以整个等式先计算.的运算
.
=
根据上面,所以整个等式第一步是先添加一个b的地址,等式大概变成这个样子[obj.b的地址]=obj={c:2}
b
[obj.b的地址]=obj={c:2}
=是从右向左运算的,而且是把=号右边的那个赋值给左边的
所以,变形后的等式运算时分为两步obj={c:2},然后[obj.b的地址]=obj。
obj={c:2}
[obj.b的地址]=obj
由于第一步的时候,obj已经指向新的地址,所以和[obj.b的地址]中的obj已经不是同一个。
obj
[obj.b的地址]
所以,第二步的时候,[obj.b的地址]=obj是把新的obj赋值给原本obj.b的地址。
所以才会出现obj输出{c:2}的情况。
{c:2}
更清晰一点,看看一个代码:
var obj = { a: 1 }; var obj2 = obj; obj.b = obj = { c: 2 }; console.log(obj); // {c:2} console.log(obj2); // { a:1, b:obj }
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,当执行下面一句
0x12341234
obj={ c:2 };
时,obj又重新申请了一块内存用于存放新的对象,0x12345678。此时,gc会释放掉原来的对象内存即0x12341234。接下来
0x12345678
gc
obj.b=obj;
注意,这两个obj是不一样的,前一个obj的地址为0x12341234,后一个为新申请的内存地址为0x12345678。然而前一个内存已经不存在了,对其操作会出错,当然,js的容错机制已经拦截了这个错误,并没有体现出来。也就是说,这是一个无意义的指令。所以最后的结果是
Object {c: 2}
也就是说,最后的这个对象只有一个成员,就是c。console.log(obj.b)当然是未定义的。
c
console.log(obj.b)
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
其实这个东西这么解释会清楚点:
根据上面,所以整个等式第一步是先添加一个
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}的情况。更清晰一点,看看一个代码:
这句话可以理解成:先进行 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
你把上面的 obj.b 改成 x 再想。
赋值操作符 “=” 永远从等式的右边往左边赋值。你从这样的方向再看一遍
这个很容易理解啊,其实就考量的运算符优先级和GC。
下面我们深入浅出去探究这个问题,如果看不懂的,欢迎跟帖咨询。
我们把上面的代码改下:
此时能正确的输出2.
当连等的时候,会从右往左依次执行。
假如此时
obj的对象地址为0x12341234,当执行下面一句时,
obj又重新申请了一块内存用于存放新的对象,0x12345678。此时,
gc会释放掉原来的对象内存即0x12341234。接下来
注意,这两个
obj是不一样的,前一个obj的地址为0x12341234,后一个为新申请的内存地址为0x12345678。然而前一个内存已经不存在了,对其操作会出错,当然,js的容错机制已经拦截了这个错误,并没有体现出来。也就是说,这是一个无意义的指令。
所以最后的结果是
也就是说,最后的这个对象只有一个成员,就是
c。console.log(obj.b)当然是未定义的。