文章目录
手写 js 深浅拷贝
- 什么场景下需要用到拷贝?
如果调用函数的时候,传入了一个对象,函数内可能会对对象进行修改,可能不符合你的期待,这
时候就需要用到拷贝
// 没有使用拷贝
var obj = {}
doSomething(obj) // 调用某个会改变obj的函数 obj可能发生变法
// 使用了拷贝
var obj = {}
var newObj = JSON.parse(JSON.stringify(obj)) doSomething(newObj) // 调用某个会改变newObj的函数
// obj还是原来的obj
- 拷贝对于简单数据类型有意义没有?
对简单数据类型没有意义,因为简单数据类型,是不可变的数据类型,在不改变内存地址的情
况下,不能改变其值。
var a = 1;
a+= 1;
console.log(a) // 2
// a的值虽然变成了2, 但是前提是:有赋值运算,a指向了全新的内存地址。
复杂数据类型,是可变的数据类型,在不改变内存地址的情况下,可以改变其值。
var arr = [1, 2, 3]
arr.push(4)
console.log(arr) // [1, 2, 3, 4]
// arr 指向的内存地址没变,但值发生了改变
-
浅拷贝指在进行数组或对象拷贝的时候只拷贝最外层,如果属性值是简单数据类型,拷贝其值,如果值是复杂数据类型,拷贝其地址。
-
深拷贝是递归的拷贝,深层次的拷贝,不管是简单数据类型还是复杂数据类型,拷贝的都是值。
-
区别
3(1) 浅拷贝,修改拷贝出来的对象,有可能影响到原对象
3(2)深靠别,修改拷贝出来的对象,不会影响到原对象
4.实现深拷贝的方式 ?
4(1)通过递归或JSON模块可以实现。
function deepClone(obj){
if(typeof obj != 'object') return obj;
return JSON.parse(JSON.stringify(obj))
}
// 测试
var obj = { name: { addr: '天边' } }
var obj1 = deepClone(obj);
obj1.name.addr = '眼前'
console.log(obj.name.addr); // 打印输出 ‘天边’
通过递归实现
// 利用递归实现深拷贝
function deepClone(obj) {
if(typeof obj !== 'object') return obj
var temp = Array.isArray(obj) ? [] : {}
for (const key in obj) {
// 判断对象是否拥有该属性
if (Object.hasOwnProperty(key)) {
// 如果 obj[key] 还是对象则进行递归拷贝
if(obj[key] && typeof obj[key] == 'object') {
temp[key] = deepClone(obj[key]) // 递归
} else {
temp[key] = obj[key]
}
}
}
return temp
}
// 测试
var obj = { name: { addr: '天边' } }
var obj1 = deepClone(obj);
obj1.name.addr = '眼前'
console.log(obj.name.addr); // 打印输出 ‘天边
好了今天的分享到此为止,后续不断分享干货