js 基本类型和引用类型的区别
基本类型和引用类型
JavaScript 规定了 7 钟原始数据类型,他们分别是:
基本类型(6):undefined、null、number、string、boolean、symbol(ES6 新引入)
引用类型(1):object
基本类型指的是简单的数据段,而引用类型指那些可能由多个值构成的对象。
他们的最大区别在于:
基本类型赋值给其他变量时,修改其他变量的值,不会影响原始值;而引用变量则会改变。
通过下面的小栗子,你可以更直观地感受:
// 基本类型
var num1 = 5
var num2 = num1
num2 = 8
console.log(num1) // 5
console.log(num2) // 8
// 引用类型
var obj1 = { a: 5, b: 6 }
var obj2 = obj1
obj2.a = 8
console.log(obj1.a) // 8
console.log(obj2.a) // 8
好奇如我,为何 JavaScript 要这么做?
都像基本类型多好,也符合我们的认知,偏偏要弄出个引用类型,消耗脑细胞。
对于一个很大的 Object,如果每次将它赋值给一个新的变量,都重新分配一个新的内存空间,对于性能损耗是很大的。
堆和栈
这便引出了 JS 中,基本类型和引用类型的数据保存机制:
-
基本类型:占据内存空间大小固定,存放在栈内存(Stack),按值来访问。
-
引用类型:占据内存空间大小不固定,存放在堆内存(Heap),并由栈内存(Stack)中存放指向该堆内存(Heap)的地址,按引用访问。
你可以这么理解:
基本类型就像现金,引用类型就像存折
下图可助你进一步理解

深拷贝和浅拷贝
那么问题来了,我就想 Object 也想基本类型一样,可以吗?
可以呀!自己写个函数来实现。
实现思路就是:
递归调用,把所有属于对象的属性类型都遍历赋给另一个对象即可。
function deepClone(obj = {}) {
if (typeof obj !== 'object' || obj == null) {
return obj
}
// 初始化返回结果
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 递归调用
result[key] = deepClone(obj[key])
}
}
return result
}

浙公网安备 33010602011771号