点击蓝色“脑洞前端”关注我哟
加个“星标”,带你揭开大前端的神秘面纱!
❝这是脑洞前端第「98」篇原创文章
❞
前一段时间群里有小伙伴问 lucifer 我一个问题:”immutablejs 是什么?有什么用?“。我当时的回答是:immutablejs 就是 tree + sharing,解决了数据可变性带来的问题,并顺便优化了性能
。今天给大家来详细解释一下这句话。
背景
我们还是通过一个例子来进行说明。如下是几个普通地不能再普通的赋值语句:
a = 1;
b = 2;
c = 3;
d = {
name: "lucifer",
age: 17,
location: "西湖",
};
e = ["脑洞前端", "力扣加加"];
上面代码的内存结构大概是这样的:
❝lucifer 小提示:可以看出,变量名( a,b,c,d,e )只是内存地址的别名而已
❞
由于 d 和 e 「的值」是引用类型,数据长度不确定,因此实际上数据区域会指向堆上的一块区域。而 a,b,c 由于长度是编译时确定的,因此可以方便地在栈上存储。
❝lucifer 小提示:d 和 e 的数据长度不确定, 但指针的长度是确定的,因此可以在栈上存储指针,指针指向堆上内存即可。
❞
实际开发我们经常会进行各种赋值操作,比如:
const ca = a;
const cb = b;
const cc = c;
const cd = d;
const ce = e;
经过上面的操作,此时的内存结构图:
可以看出,ca,cb,cc,cd,ce 的「内存地址都变了,但是值都没变」。原因在于变量名只是内存的别名而已,而赋值操作传递的是 value。
由于目前 JS 对象操作都是 mutable 的, 因此就有可能会发生这样的 “bug”:
cd.name = "azl397985856";
console.log(cd.name); // azl397985856
console.log(d.name); // azl397985856
上面的 cd.name
「原地修改」了 cd 的 name 值,这会影响所有指向 ta 的引用。
比如有一个对象被三个指针引用,如果对象被修改了,那么三个指针都会有影响。
你可以把指针看成线程,对象看成进程资源,资源会被线程共享。多指针就是多线程,当多个线程同时对一个对象进行读写操作就可能会有问题。
于是很多人的做法是 copy(shallo