从一道面试题看javascript连续赋值问题

2,886 阅读3分钟

    前几天在一个技术群吹水,有人抛出来一道面试题,竟被难住了,题目如下:

 var a = {n:1};
 a.x = a = {n:2};
 alert(a.x);    // undefined

    不知各位大佬答案是啥,我承认我答错了,,,为什么呢?我们仔细研究一下:

    第一种可能:js语法不支持连续赋值,虽然没报错,但是不能这么写。然后测试一下:

var a = 1;
b = a = 2;
console.log(a, b);    // 2 2

     OK,这种猜测不成立,那仔细看两者差别,数据类型不同。

    数据类型与赋值运算符

     我们回忆一下js数据类型构成,我们知道js数据类型分为基础数据类型和引用数据类型两种,其中基础数据类型有:String、Number、boolean、null、undefined五种,引用数据类型有三种:object、array、function(广义的Object)。那么对于不同的数据类型,使用赋值运算符有什么差异呢?

    我们看一段代码:

let a = 1;

      这句代码非常好理解,即声明了一个名为 a 的变量,a 的值为 1。变量通俗理解就是一个容器,变量的值即为容器中存放的内容。上面的代码即可以理解为一个名叫 a 的容器,容器中放了 1这条数据。用一种更符合计算机原理的方式来解释变量,那就是把变量理解为电脑中的内存,声明一个变量即在电脑的内存中开辟了一块空间,给变量赋值即将值存储在该空间中。基本数据类型,这样理解是没有问题的,在看下面这段代码:

let arr = [1, 2, 3 ]
brr = arr;brr.push(4);
console.log(arr);  //     [1, 2, 3, 4 ]

      按照之间的结果分析,结果应该是 [1, 2, 3], 为什么和b一样了呢?这就和数据类型有关了

      对于基本数据类型的赋值运算,计算机执行的操作是将 a 空间中存储的值拷贝了一份给 b 空间,并存储在其中。

**       对于引用数据类型的赋值运算,计算机执行的操作并不是将 a 的值拷贝一份给 b ,而是将 a 空间在内存中的地址赋给了 b 。**

       所以当我们再访问 b 时,访问到的其实是 a 在内存中的地址,该地址再自动将我们引导到 a 空间,也就是我们访问到了 a 空间中存储的值,即 a 的值。也就是 b 并没有拷贝一个和 a 相同的数据存储在自己的空间中,而是 b 获得了一个指向 a 的指针。流程如下图:

    

   引用数据类型连续赋值那一瞬间发生了什么?

   我们从头开始,如下图所示:

如何验证上图的猜想是成立的呢?我们可以将原先的值同时赋给两个变量,在进行同样操作之后,看下变量的变化,猜想验证如下:

let a = b = { n : 1};
a.x = a = { n : 2};
console.log(a);          // {n:2}
console.log(b);          // {n:1, x: {n:2}}

    经过验证,猜想成立。不知我阐述的够不够明白,不足之处,希望各位指出。


如有问题,欢迎探讨,如果满意,请手动点赞,谢谢!🙏

及时获取更多姿势,请您关注!!!