数据类型
Table of Contents
JavaScript 中的数据类型有:String
、Number
、Boolean
、Null
、Undefined
、Object
、Symbol
七大类。其中常见的有前六个。
数据分类
String
、Number
、Boolean
、Null
、Undefined
被称为基础类型
数据,而 Object
类型的数据被称为引用类型
数据。
数据存储
基础类型
的数据直接存储于栈内存(stack)
中。而 引用类型
的数据存储于堆内存(heap)
中,栈内存中存储的是数据在堆内存中的引用地址,而不是真正的数据。
网络上很多人的博客都配有示意图,很容易搜索到,这里就不放示意图了。
数据拷贝
基本类型
基础类型的数据,进行数据的拷贝是真正的数据拷贝,拷贝完的两份数据没有任何关联
(在这个层面上叫做两个变量不相等
)。例如:
var a = 1;
var b = a;
console.log(a); // 1
console.log(b); // 1
console.l(a === b); // true
b = 2;
console.log(a); // 1
console.log(b); // 2
console.log(a === b); // false
可以看出,a 和 b 完全没有关系,更改 b 的值不影响 a 的值。
引用类型
引用类型的数据在进行比较的时候,比较的是堆内存地址:
var a = { name: 'a' };
var b = a;
console.log(a); // { name: 'a' }
console.log(b); // { name: 'a' }
console.l(a === b); // true
b.name = 'b';
console.log(a); // { name: 'b' }
console.log(b); // { name: 'b' }
console.log(a === b); // true
这个例子看出来,b 与 a 是有关联的,将 a 的值(引用地址)拷贝给 b 之后,b 中存储的是和 a 完全一样的引用地址,那么更改 b 中的值(b.name = 'b'
),也就是更改了真正的数据,那么打印出 a 的时候,发现 a 中的数据也受到了影响,因为 a 和 b 都指向的是同一个引用地址。因此表现为更改 b 的值,a 的值也受到了影响,拷贝完的两份数据是有关联的
(在这个层面上也叫做两个变量不完全不等
)。
以此类推,如果引用类型
的数据在堆内存中又引用了其他的引用类型
的数据呢(比如对象的属性值也是一个对象)?那么比较两个数据是否完全相等或完全不等就相对麻烦。如果不搞清楚这两个概念,可能会导致一些意外的错误,也正因为这个缘故,引出了对象的深拷贝
问题(如何使两个对象一模一样但完全不等),这也是前端工程师的经典面试题之一。
目前没有真正的
对象深拷贝
方法,常用的方法有JSON.parse(JSON.stringify(obj))
以及自行编写的deepCopy
函数,递归进行拷贝。虽然这些都不是真正的对象深拷贝,但是在实践中,这两个方法能解决大部分问题。
完。