js对象等号赋值的bug

1
2
3
4
5
6
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
 
console.log(a.x);
console.log(b.x);
有道题是这样的,觉得很奇葩,分析一下

 

 

1.对象 引用类型

对象属于引用类型,c,java,js里面都是的,对象就是引用类型,包括数组。

上面的a是引用类型,a保存的是对象 {n: 1}的地址,对这个对象的引用。b = a 。把a里面的地址赋值给了b,b也指向{n: 1}这个对象的物理地址。所以,a 一旦做赋值更改,修改的是a对引用的修改。b也同时修改,b修改的时候,a也会被修改。这就是引用类型。

堆和栈。堆是真实的{n:1} 。栈里面存放的是堆的物理地址,值比较小。根据栈的地址去找堆里面的数据。

 

2.

1
2
3
4
var a = {n:1};
var b = a;
a.x = a = {n:2};
console.log(a===b.x); //true

  第二个奇葩结果

 

3.

https://blog.csdn.net/qiphon3650/article/details/78860973

我把这篇看了,然后觉得还是不理解

 就这句: 执行a.x=a,此时a已经指向了新对象,而a.x因为在执行前保留了原引用。

不理解的点是 a都已经改变指向了,a指向了{n: 2},a.x里面的a的指向当然也改变成了{n: 2},为什么,a.x还会保留原引用

 

 

4.我又看了别人写的,觉得这样比较好绕回来

a.x的运算优先级最高

也就是说

1
2
3
4
var a = {n:1};
var b = a;
a.x = a = {n:2};
console.log(a===b.x); //true

这段代码可以写成这样

1
2
3
4
var a = {n:1};
var b = a;
a.x = (a = {n:2});
console.log(a===b.x); //true

  

这样就解释通了

       1.a指向 {n: 1};   ---> var a = {n: 1};

       2.b指向 a指向的这个 {n: 1}  ---> var b = a;

  3.计算 a.x = (a = {n: 2});    a.x的值是 后面值的结果,后面的值先不管。此时 a.x = (某个值),是先计算的。a.x 这个a 指向并没有被         改变

  所以. a.x 里面的a仍然是原来的 {n: 1};a.x里面的值是后面( a = {n: 2})这个结果的返回值。这个返回值是 {n: 2};

       4.所以拆分成a.x = { n: 2 }; 然后原来的a的值被 a = {n: 2},b是对原来对象的引用; a 最后赋值的结果是a = {n: 2};

        所以。a.x是underfined,因为新的a里面并没有 x这个属性

 

 

所以我觉得这个赋值运算的结果,a = {n: 2}这个a并没有更改引用的时候,它的返回值就已经确定了,就先赋值给原来的a.x里面的a了。我只是猜想。。。连等式可能并不会去计算过程,其中所有的值都直接被最后一个等号的值给赋值,其中,引用类型的赋值. 会优先赋值计算。

这个图表示最后的结果,并不能表示赋值过程。

 

 

posted on   chenyi4  阅读(1766)  评论(1编辑  收藏  举报

编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示