这篇文章主要介绍JS中基本类型与对象之间的区别。
对象包括普通对象,数组以及函数。普通对象是基本类型的混合,同时其中也可包含对象。
需要理解基本类型和对象的区别就得介绍另一个东西,JS引擎底层存储它们的方式。JS引擎底层将分配到的内存分为代码区和数据区,代码主要用来存储变量名,而赋值的数据则存储在数据区,而数据区又分为Stack栈内存和Heap堆内存。
- Stack栈内存主要用于存储基本数据类型以及对象的Heap地址。
- Heap堆内存存储对象。
所以,基本类型和对象的存储是不同的。这一区别关系到数据的使用及改变。简单的说,基本类型数据是使用拷贝存储的,一个数据赋值给一个或多个变量是通过拷贝的,也就是说改变它们的赋值并不会影响其他声明的value数据。
而对象则不同,对象并不会拷贝存储,在给声明赋值时拷贝的只是Heap内存地址,而并不真正拷贝对象,所以在之后改变对象内属性时,对指向同一对象的声明都会有影响,下面看几个例子。
var a = 1;
var b = a;
b = 2;
上面a
的值仍然是1
,因为基本数据类型是通过拷贝存储的。
var a = {name: 1};
var b = a;
b.name = 2;
此时再使用a.name
得到的是2
,因为声明a
、b
只是拥有同一对象的相同Heap地址。通过直观的内存图能更好地理解。
从图上就能看出,c、d指向的是同一个对象。另外,如果不是改变对象的属性,而是赋值另一个对象则不会对其他变量产生影响(即使两个对象内部完全相同,也仍然是不同对象)。
深复制和浅复制
深浅复制就是基于底层存储数据方式的不同产生的,基本类型之间的赋值,变化都属于深复制,而对对象的引用则属于浅复制。
另外,如果一个对象失去了引用,即没有变量引用它,那么浏览器就会将此对象当做垃圾回收以释放内存。
关于不同数据类型之间的相互转换可参考我的另一篇博客JS里的数据类型。