深拷贝和浅拷贝的方法,深拷贝的方法及优缺点

首页 > 经验 > 作者:YD1662022-10-24 22:44:42

由于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的序列化和反序列化方法,可以实现简易对象深拷贝,但此种方法有较大的限制:

  1. 会忽略属性值为undefined的属性
  2. 会忽略属性为Symbol的属性
  3. 不会序列化函数
  4. 不能解决循环引用的问题,直接报错

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

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.