浅谈Javacript浅拷贝和深拷贝的实现
2021/7/30 17:08:06
本文主要是介绍浅谈Javacript浅拷贝和深拷贝的实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
浅拷贝和深拷贝
如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝;如果B没变,那就是深拷贝,深拷贝与浅拷贝的概念只存在于引用数据类型。
1. 浅拷贝
var obj1 = { name: "帅哥", age: 20, speak: function () { console.log("我是" + this.name); } }; var obj2 = obj1; // 当修改obj2的属性和方法的时候,obj1相应的属性和方法也会改变 obj2.name = "帅男"; console.log(obj1); console.log(obj2);
2. 深拷贝
JavaScript中:Array:slice()、concat()、Array.from()、… 操作符:只能实现一维数组的深拷贝
1.slice()方法:
var arr1 = [1, 2, 3, 4]; var arr2 = arr1.slice(); arr2[0] = 200; console.log(arr1); console.log(arr2);
2.concat()方法:
var arr1 = [1, 2, 3, 4]; var arr2 = arr1.concat(); arr2[0] = 200; console.log(arr1); console.log(arr2);
- Array.from()方法:
var arr1 = [1, 2, 3, 4]; var arr2 = Array.from(arr1); arr2[0] = 200; console.log(arr1); console.log(arr2);
- … 扩展运算符:
var arr1 = [1, 2, 3, 4]; var arr2 = [...arr1]; arr2[0] = 200; console.log(arr1); console.log(arr2);
- Object.assign()、… 操作符:只能实现一维对象的深拷贝
Object.assign()方法:
var obj1 = { name: "张三", age: 20, speak: function () { console.log("我是" + this.name); } }; var obj2 = Object.assign({}, obj1); // 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变 obj2.name = "李四"; console.log(obj1); console.log(obj2);
- … 扩展运算符:
var obj1 = { name: "张三", age: 20, speak: function () { console.log("我是" + this.name); } }; var obj2 = { ...obj1 }; // 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变 obj2.name = "李四"; console.log(obj1); console.log(obj2);
JSON.parse(JSON.stringify(obj)):可实现多维对象的深拷贝,但会忽略 undefined 、 任意的函数 、Symbol 值
var obj1 = { name: "帅哥", age: 20, birthday: { year: 1997, month: 12, day: 5 }, speak: function () { console.log("我是" + this.name); } }; var obj2 = JSON.parse(JSON.stringify(obj1)); // 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变 obj2.name = "帅男"; console.log(obj1); console.log(obj2);
进行JSON.stringify()序列化的过程中,undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时),由上面可知,JS 提供的自有方法并不能彻底解决Array、Object的深拷贝问题,因此我们应该自己实现。
手写一个通用版的深拷贝
// obj 就是需要拷贝的对象 function deepClone(obj, has = new WeakMap()) { // 检查类型 if (obj == null) return obj; if (obj instanceof Date) return obj; if (obj instanceof RegExp) return obj; if (!(typeof obj == "object")) return obj; const newObj = new obj.constructor; //构造新对象 // 防止自引用导致的死循环 if (has.get(obj)) return has.get(obj); has.set(obj, newObj); for (let key in obj) { // 循环遍历属性及方法 if (obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key]); } } return newObj; // 将新对象返回 }
测试:
var obj1 = { name: "帅哥", age: 20, birthday: { year: 1997, month: 12, day: 5 }, speak: function () { console.log("我是" + this.name); } }; var obj2 = deepClone(obj1); // 当修改obj2的属性和方法的时候,obj1相应的属性和方法不会改变 obj2.name = "帅男"; console.log(obj1); console.log(obj2);
这篇关于浅谈Javacript浅拷贝和深拷贝的实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-26大厂数据结构与算法教程:入门级详解
- 2024-12-26大厂算法与数据结构教程:新手入门指南
- 2024-12-26Python编程入门指南
- 2024-12-26数据结构高级教程:新手入门及初级提升指南
- 2024-12-26并查集入门教程:从零开始学会并查集
- 2024-12-26大厂数据结构与算法入门指南
- 2024-12-26大厂算法与数据结构入门教程
- 2024-12-26二叉树入门教程:轻松掌握基础概念与操作
- 2024-12-26初学者指南:轻松掌握链表
- 2024-12-26平衡树入门教程:轻松理解与应用