JS浅拷贝和深拷贝原理与实现方法分析
一、浅拷贝
浅拷贝是将一个对象的属性值复制到另一个对象,新对象和旧对象的各个属性指向的是同一个对象。这意味着修改其中一个对象的属性会同时修改另一个对象的属性。
1. 实现方法
1.1 Object.assign()
ES6引入了Object.assign()方法,该方法可以用来浅拷贝对象。
let obj1 = { name: '张三', age: 18 };
let obj2 = Object.assign({}, obj1);
console.log(obj2); // { name: '张三', age: 18 }
1.2 手写浅拷贝
也可以手动编写一个浅拷贝的方法,该方法使用循环遍历原对象的属性并将其复制到新对象上。
function shallowClone(obj) {
let newObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
let obj1 = { name: '张三', age: 18};
let obj2 = shallowClone(obj1);
console.log(obj2); // { name: '张三', age: 18 }
2. 示例说明
2.1 使用Object.assign()实现浅拷贝
let obj1 = { name: '张三', age: 18 };
let obj2 = Object.assign({}, obj1);
obj1.age = 20;
console.log(obj2.age); // 输出 18
这里通过Object.assign()方法将obj1对象浅拷贝到obj2对象上。当修改obj1的属性age为20时,obj2对象的属性age并未改变,由此可以证明这是一个浅拷贝。
2.2 手写浅拷贝实现
function shallowClone(obj) {
let newObj = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = shallowClone(obj1);
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山', '看电影']
这里使用手写的浅拷贝方法,将obj1对象浅拷贝到obj2对象上。当修改obj1的属性hobby,将新元素'看电影'加入hobby属性时,obj2的hobby属性同样改变了,由此可以证明这是一个浅拷贝。
二、深拷贝
深拷贝是将一个对象的属性值复制到另一个对象,新对象指向的是完全独立的新对象,对新对象的修改不会影响原对象。
1. 实现方法
1.1 JSON.parse()和JSON.stringify()
可以通过JSON.stringify()将对象转换为字符串,然后再通过JSON.parse()将字符串转换回对象,从而实现深拷贝。这种方法的局限是,如果对象中存在函数、正则表达式等特殊类型,将无法正确处理。
let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']
1.2 手写递归深拷贝
手写递归深拷贝方法,可以确保所有类型的属性都能被正确地拷贝。
function deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Date) return new Date(obj);
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = deepClone(obj1);
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']
2. 示例说明
2.1 使用JSON.parse()和JSON.stringify()实现深拷贝
let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']
这里使用了JSON.parse()和JSON.stringify()方法,将obj1对象深拷贝到obj2对象上。当修改obj1的属性hobby,将新元素'看电影'加入hobby属性时,obj2的hobby属性并没有改变,由此可以证明这是一个深拷贝。
2.2 手写递归深拷贝实现
function deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj instanceof RegExp) return new RegExp(obj);
if (obj instanceof Date) return new Date(obj);
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
let obj1 = { name: '张三', age: 18, hobby: ['游泳', '爬山'] };
let obj2 = deepClone(obj1);
obj1.hobby.push('看电影');
console.log(obj2.hobby); // 输出 ['游泳', '爬山']
这里使用手写的递归深拷贝方法,将obj1对象深拷贝到obj2对象上。当修改obj1的属性hobby,将新元素'看电影'加入hobby属性时,obj2的hobby属性并没有改变,由此可以证明这是一个深拷贝。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS浅拷贝和深拷贝原理与实现方法分析 - Python技术站