Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一道题目看堆栈内存的演变 #19

Open
itstrive opened this issue Aug 9, 2019 · 1 comment
Open

一道题目看堆栈内存的演变 #19

itstrive opened this issue Aug 9, 2019 · 1 comment
Labels
article small article js About Js something

Comments

@itstrive
Copy link
Owner

itstrive commented Aug 9, 2019

说明: 图画的很糙,大家明白意思就好,还有引用赋值是不是这样的,大家可以提出自己的意见和论证。

题目是这样的

var a = {n:1};
var b = a;
a.x = a = {n:2};

console.log(a.x); //undefined
console.log(b.x); //{n:2}

接下来看下内存堆栈的演变

  • 当经过
var a = {n:1};

image

  • 当经过
var a = {n:1};
var b = a;

image

  • 最后一句代码很关键,发生挺多事情

为了理解最后一句,先看下我总结的(自己瞎写的,无从考证),不成文的规定

比如 var a = b = c = d =1; 像这样的、栈里面的赋值是从右向左赋值的(栈是后进先出)
但是如果是引用对象,比如: var a = b = c = d = {n:123} 就是从左往右赋值的(引用是标记)。
一个不成文的约定,记住暂时。

所以上述最后一句代码,咱们可以拆成:

a.x = {n:2} 
a = {n:2}
  • 当经过 a.x = {n:2}

image

  • 最后经过 a = {n:2}, 把 a的指向换成了新的

image

@itstrive itstrive added article small article js About Js something labels Aug 9, 2019
@itstrive
Copy link
Owner Author

itstrive commented Aug 9, 2019

以上是论证1,可以看出强行加了一个引用赋值是从左往右的(简直就是瞎说),这个可以说是错误的,因为
js赋值操作是 从右到左, 可以查证的地方很多,自行百度。

接下来看另一个论证观点: 每个观点都是可以查证的(不提供链接,自行百度、google);

总结下来两点:

  1. 运算符优先级 .的优先级高于 =, 所以先执行 a.x, 堆内存中的 {n:1} 就会变成 {n:1, x:undefined},相应的 b.x也变了,因为指向的是同一个对象

  2. 赋值操作是从右到左,所以先执行 a={n:2},a的引用就被改变了。但是需要特别注意,这个值随后又赋值给了 a.x,这时候,其实是第一步的 {n:1, x:undefined} 那个对象。也就是 b.x

内存演变图如下:

a.x = a = {n:2} 开始,上两句都很简单

  • a.x = ; 先执行
    image

  • 随后赋值动作,从右向左
    image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
article small article js About Js something
Projects
None yet
Development

No branches or pull requests

1 participant