🙏废话不多说系列,直接开整🙏
1. 完整源码
核心功能:
- 方式一:使用遍历的方式;
- 方式二:防止两个对象是相互引用的;(升级版)
- 方式三:使用 JSON.parse 和 JSON.stringify(普遍性的拷贝方法);
// 方法一:使用遍历的方式
function deepCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
if (obj1 && typeof obj1 === "object") {
for (var i in obj1) {
if (obj1.hasOwnProperty(i)) {
// 如果子属性为引用数据类型,递归复制
if (obj1[i] && typeof obj1[i] === "object") {
obj2[i] = deepCopy(obj1[i]);
} else {
// 如果是基本数据类型,只是简单的复制
obj2[i] = obj1[i];
}
}
}
}
return obj2;
}
// 升级:(防止两个对象是相互引用的)
function deepCopy(obj1) {
var obj2 = Array.isArray(obj1) ? [] : {};
if (obj1 && typeof obj1 === "object") {
for (var i in obj1) {
var prop = obj1[i]; // 避免相互引用造成死循环,如obj1.a=obj
if (prop == obj1) {
continue;
}
if (obj1.hasOwnProperty(i)) {
// 如果子属性为引用数据类型,递归复制
if (prop && typeof prop === "object") {
obj2[i] = (prop.constructor === Array) ? [] : {};
arguments.callee(prop, obj2[i]); // 递归调用
} else {
// 如果是基本数据类型,只是简单的复制
obj2[i] = prop;
}
}
}
}
return obj2;
}
// 方法二:使用 JSON.parse 和 JSON.stringify(普遍性的拷贝方法)
var b = JSON.parse(JSON.stringify(a));
// 方法三:
/**
* @param {object/array} 数组或对象
* @return {object/array} 数组或对象
*/
function deepClone(obj = {}) {
if (typeof obj !== 'object' || obj == {}) {
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;
}
// 实例1:深拷贝数组
let arrDemo = [1,2,3];
let arrDemoCloned = deepClone(arrDemo);
arrDemoCloned.push(4);
console.log(arrDemo); // [1, 2, 3]
console.log(arrDemoCloned); // [1, 2, 3, 4]
// 实例2:深拷贝对象
let objDeepTree = {
name: "Drew",
age: 23,
habbit: {
pingpang: "乒乓球",
basketball: "篮球",
football: "足球"
}
}
let objDeepTreeCloned = deepClone(objDeepTree);
objDeepTreeCloned.sex = "男"
objDeepTreeCloned.habbit.internet = "网络"
console.log(objDeepTree); // {"age":23,"habbit":{"basketball":"篮球","football":"足球","pingpang":"乒乓球"},"name":"Drew"}
console.log(objDeepTreeCloned); // {"age":23,"habbit":{"basketball":"篮球","football":"足球","internet":"网络","pingpang":"乒乓球"},"name":"Drew","sex":"男"}
2. 示例
(1)深拷贝——对象
let student = {
id: 1,
name: 'Drew',
age: 23
}
// 方法一:使用 深拷贝函数
let deepStudent = deepCopy(student);
deepStudent.sex = "男";
console.log(deepStudent); // {id: 1, name: "Drew", age: 23, sex: "男"}
console.log(student);// {id: 1, name: "Drew", age: 23}
// 方法二:使用 JSON 类
let deepStudentByJSON = JSON.parse(JSON.stringify(student));
deepStudentByJSON.sex = "女";
console.log(deepStudentByJSON); // {id: 1, name: "Drew", age: 23, sex: "女"}
console.log(student);// {id: 1, name: "Drew", age: 23}
(2)深拷贝——数组
let arr = [1,2,3];
// 方法一:使用 深拷贝函数
let deepArr = deepCopy(arr);
deepArr.push(4);
console.log(deepArr);
console.log(arr);
// 方法二: 使用 JSON 内置类
let deepArrByJSON = JSON.parse(JSON.stringify(arr));
deepArrByJSON.push(66);
console.log(deepArrByJSON);
console.log(arr);
反思
(1)如果一个对象的属性时多层次的呢?(此时需要 扩展 deepCopy 的拷贝层级关系了 => lodash 库了解下)
(2)如果一个对象中含有方法呢?(此时 JSON 类的方法就无效果了)
(3)lodash JS工具库的学习:www.jianshu.com/p/d46abfa4d…
🙏至此,非常感谢阅读🙏