深拷贝、浅拷贝的方法

深拷贝、浅拷贝的方法目录 浅拷贝 深拷贝 深拷贝 与浅拷贝 概念 深浅拷贝出现的前提 应用类型的数据 对象和数组 深拷贝就是把目标对象里面的数据一个一个都复制下来 创建出一个一模一样的 存放地 址不一样 互不影响 就像真假美猴王 改变其中一个对象中的内容

大家好,我是讯享网,很高兴认识大家。

目录

浅拷贝

深拷贝


深拷贝浅拷贝概念: 

深浅拷贝出现的前提: 应用类型的数据(对象和数组) 深拷贝就是把目标对象里面的数据一个一个都复制下来,创建出一个一模一样的,存放地 址不一样,互不影响。就像真假美猴王。改变其中一个对象中的内容,另一个对象不会受 到任何影响。 浅拷贝就是单纯的复制内存地址,并没有复制对象本身,新旧两个都共享同一个内存。一荣 俱荣一损共损的样子,任何一个对象里改变某一个属性值,那么另一个也会随之发生改变 区别:浅拷贝只能复制第一层,想要深度拷贝的话就要用到深拷贝了 

讯享网

深拷贝和浅拷贝的区别

1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用

2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”

接下来我们就以下面这个obj1对象为例子,进行深浅拷贝的演示

讯享网  const obj1 = {     a: 1,     b: undefined,     arr: [1, 2, 3],     fun: () => {}   }

浅拷贝
讯享网

 1.Object.assign()方法

const obj2 = Object.assign({},obj1)


缺点:这里就会发现使用Object.assign()只能深拷贝一级属性,二级以上的属性(引用类型)就是浅拷贝了

2.扩展运算符

讯享网const obj2 = {...obj1}

 

缺点:这个方法和上面使用Object.assign()方法使用的结果都是一样的。只能深拷贝一级属性,二级以上属性(引用类型)就是浅拷贝了

3.arrayObject.slice(start,end)、arrayObject.concat(arrayX,...,arrayX)

用法:

arrayObject.slice(start,end) 
  • Object.assign()
  • 函数库lodash的_.clone方法
  • 展开运算符…
  • Array.prototype.concat()
  • Array.prototype.slice()

深拷贝

1.写一个递归(推荐,比较完美的解决方案)
封装一个DeepClone的深拷贝函数

讯享网  function DeepClone(data) {     const newData = Array.isArray(data) ? [] : {}     for (let key in data) {       if (data[key] && typeof data[key] === 'object') {         newData[key] = DeepClone(data[key])       } else {         newData[key] = data[key]       }     }     return newData   }
//deepClone 深拷贝 function deepClone(source) { if (!source || typeof source !== 'object') { return source; } const targetObj = source.constructor === Array ? [] : {}; for (const keys in source) { if (source.hasOwnProperty(keys)) { if (source[keys] && typeof source[keys] === 'object') { targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = deepClone(source[keys]); } else { targetObj[keys] = source[keys]; } } } return targetObj; } 

//调用他

讯享网const obj2 = DeepClone(obj1)

 2.用for…in实现遍历和复制

function deepClone(obj) { let result = typeof obj.splice === "function" ? [] : {}; if (obj && typeof obj === 'object') { for (let key in obj) { if (obj[key] && typeof obj[key] === 'object') { result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候,递归调用deepClone,即在吧某个值对象复制一份到新的对象的对应值中。 } else { result[key] = obj[key];//如果对象的属性值不为object的时候,直接复制参数对象的每一个键值到新的对象对应的键值对中。 } } return result; } return obj; } let testArray = ["a", "b", "c", "d"]; let testRes = deepClone(testArray); console.log(testRes); console.log(typeof testRes[1]); let testObj = { name: "weiqiujuan", sex: "girl", age: 22, favorite: "play", family: {brother: "son", mother: "haha", father: "heihei"} }; let testRes2 = deepClone(testObj); testRes2.family.brother = "weibo"; console.log(testRes2); 

3.利用数组的Array.prototype.forEach进copy

讯享网let deepClone = function (obj) { //Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。 let copy = Object.create(Object.getPrototypeOf(obj)); //Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名 //(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组。 let propNames = Object.getOwnPropertyNames(obj); propNames.forEach(function (items) { // 方法返回指定对象上一个自有属性对应的属性描述符。 //(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性) let item = Object.getOwnPropertyDescriptor(obj, items); Object.defineProperty(copy, items, item); }); return copy; }; let testObj = { name: "weiqiujuan", sex: "girl", age: 22, favorite: "play", family: {brother: "wei", mother: "haha", father: "heihei"} } let testRes2 = deepClone(testObj); console.log(testRes2); 

4.JSON转换方法

  const obj1 = {     a: 1,     b: undefined,     arr: [1, 2, 3],     fun: () => {}   }
讯享网const obj2 = JSON.parse(JSON.stringify(obj1)) 

//这个方法可以,只不过function和undefined这种情况下无法复制

缺点:你看到这里就会发现数据类型是 function 和 undefined 情况下无法复制,其他的都可以进行深层次的拷贝

5.loadash函数库
函数库lodash,也有提供_.cloneDeep用来做深拷贝6.

let lodash = require('lodash'); let list = [{ name: 'Tom' }]; let copyList = lodash.cloneDeep(list); copyList[0].name = 'Jerry' console.log(list[0].name);      // Tom console.log(copyList[0].name);      // Jerry
小讯
上一篇 2025-04-01 17:18
下一篇 2025-02-18 12:02

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/54404.html