13.js赋值运算的过程
示例
这道题的结果是什么?
var a = {
n:1};
var b = a;
a.x = a = {
n:2};
console.log(a.x);
console.log(b.x);
正确答案是
undefined
{
n:2}
这道题考察的是js赋值运算的过程
我们以a=1
这个赋值运算为例,当我们执行a=1
这段代码时,js引擎的处理过程是这样的
- 找到变量a的内存地址,准备赋值
- 运算右侧表达式代码,得到表达式结果
- 将右侧表达式的结果存入a的内存地址指向的内存中
- 返回整个表达式的结果为右侧表达式的结果
第4点的解释是这样的:
console.log(a=1) // output 1
那我们再回到示例题,解释一下示例代码的执行过程
- 在栈内存中创建a变量,它的地址值指向堆内存中的一块内存区域
- 右侧表达式返回一个对象
{n:1}
- 将
{n:1}
存入a的地址值指向的堆内存中 - 在栈内存中创建b变量,并设置b的地址值与a相同(此时a与b指向同一个内存区域)
- 将
a.x = a = {n:2}
分为左部a.x
和右部a = {n:2}
- 我们知道a当前指向的内存值是
{n:1}
,并没有x
属性,由于js是可以手动新建属性的.所以此时会在a的内存中创建x
属性,即a指向的值为{n:1,x:undefined}
- 现在处理右部,我们可以发现右部也可以继续细分为左部和右部,我们记为小左部和小右部
- 找到小左部的内存地址,即a的内存地址
- 处理小右部的表达式,表达式结果为
{n:2}
; - 将小右部结果赋值给小左部的内存地址指向的区域,但是要注意的是小右部的结果是一个对象,那么此时a与原来指向的内存块断开引用关系,获得新的引用地址值,并且指向{n:2},即a的指向为
{n:2}
- 此时能获得
a = {n:2}
这个表达式的返回值为{n:2}
- 将其赋值给左部内存指向,此时左部内存指向为
{n:1,x:{n:2}}
,即b的指向为{n:1,x:{n:2}}
最终指向示例图如下所示
总结:js入门很简单,但是深挖的话里面的细节确实挺多的,知识深度还是不太够