由于JavaScript 中对象是引用类型,保存的是地址,深、浅拷贝的区别是,当拷贝结束后,在一定程度上改变原对象中的某一个引用类型属性的值,新拷贝出来的对象依然受影响的话,就是浅拷贝,反之就是深拷贝。
浅拷贝的几种实现方法
第一种方法: Object.assign() 会拷贝原始对象中的所有属性到一个新对象上,如果属性为对象,则拷贝的是对象的地址,改变对象中的属性值,新拷贝出来的对象依然会受影响。
var obj = {
name: '张三',
age: 23,
isStudent: false,
job: {
name: 'FE',
money: 12
}
}
var newObj = Object.assign({}, obj);
obj.job.money = 21;
console.log(newObj.name); // 输出张三
console.log(newObj.age); // 输出23
console.log(newObj.job.money);// 输出21,受影响
第二种方法:... 扩展运算符是ES6 新增加的内容
var obj = {
name: '张三',
age: 23,
isStudent: false
}
var newObj = {...obj};
console.log(newObj.name); // 输出张三
console.log(newObj.age); // 输出23
深拷贝几种实现方式
第一种方法: 利用JSON 的序列化和反序列化方法,可以实现简易对象深拷贝,但此种方法有较大的限制:
- 会忽略属性值为
undefined 的属性 - 会忽略属性为
Symbol 的属性 - 不会序列化函数
- 不能解决循环引用的问题,直接报错
var obj = {
name: '张三',
age: 23,
address: undefined,
sayHello: function() {
console.log('Hello');
},
isStudent: false,
job: {
name: 'FE',
money: 12
}
}
var newObj = JSON.parse(JSON.stringify(obj));
obj.job.money = 21;
console.log(newObj.name); // 输出张三
console.log(newObj.age); // 输出23
console.log(newObj.job.money); // 输出12
console.log(newObj.address); // 报错
console.log(newObj.sayHello());// 报错
第二种: 实现自己简易的深拷贝函数
function deepClone(obj) {
function isObject(o) {
return (typeof o === 'object' || typeof o === 'function') && o !== null;
}
if(!isObject(obj)) {
throw new Error('非对象');
}
var isArray = Array.isArray(obj);
var newObj = isArray ? [...obj] : {...obj};
Reflect.ownKeys(newObj).forEach(key => {
newObj[key] = isObject(newObj[key]) ? deepClone(newObj[key]) : newObj[key];
})
return newObj;
}
var obj = {
name: 'AAA',
age: 23,
job: {
name: 'FE',
money: 12000
}
}
var cloneObj = deepClone(obj);
obj.job.money = 13000;
console.log(obj.job.money); // 输出13000
console.log(cloneObj.job.money);// 输出12000
第三种方法: 使用lodash第三方函数库实现(需要先引入lodash.js)
var obj = {
name: '张三',
age: 23,
isStudent: false,
job: {
name: 'FE',
money: 12
}
}
var newObj = _.cloneDeep(obj);
obj.job.money = 21;
console.log(newObj.name); // 输出张三
console.log(newObj.age); // 输出23
console.log(newObj.job.money);// 输出12,不受影响
如若转载,请注明出处:开源字节 ? https://sourcebyte.cn/article/145.html
|