欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > js-17-对数组、对象进行浅拷贝和深拷贝

js-17-对数组、对象进行浅拷贝和深拷贝

2025/2/23 1:56:36 来源:https://blog.csdn.net/m0_64150479/article/details/142526384  浏览:    关键词:js-17-对数组、对象进行浅拷贝和深拷贝

目录

  • 数组
    • 一、浅拷贝
      • 1. 展开运算符...
      • 2. Array.prototype.slice()
    • 二、深拷贝
      • 1. JSON方法
      • 2. 递归函数
  • 对象
    • 一、浅拷贝
      • 1. Object.assign()
      • 2. 展开运算符...
    • 二、深拷贝
      • 1. JSON方法
      • 2. 递归函数

自己总结的一些方法,可能有不到位的地方,欢迎指出

数组

一、浅拷贝

1. 展开运算符…

let arr1 = [1,2,'3',true, { name: '李华'}]
let arr2 = [...arr1] // arr2=[1,2,'3',true, { name: '李华'}]arr2[0] = 0 // 修改浅拷贝数组中的基本类型元素,原始数组不受影响
arr2[3] = false // 修改浅拷贝数组中的基本类型元素,原始数组不受影响
arr2[4].name = '小帅' // 修改浅拷贝数组中的对象的属性,由于对象是引用类型,所以原始数组中的对象也会受到影响console.log(arr1) // [1,2,'3',true, { name: '小帅'}]
console.log(arr2) // [0,2,'3',false,{ name: '小帅'}]

2. Array.prototype.slice()

let arr1 = [1, 2, '3', true, { name: '李华'}]
let arr2 = arr1.slice() // arr2=[1,2,'3',true,{ name: '李华'}]arr2[0] = 0
arr2[3] = false
arr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '小帅' }]
console.log(arr2) // [0, 2, '3', false, { name: '小帅' }]

二、深拷贝

1. JSON方法

注意:此方法不能处理函数、undefined、Symbol和循环引用

    let arr1 = [1, 2, '3', true, { name: '李华'}]let arr2 = JSON.parse(JSON.stringify(arr1))arr2[0] = 0arr2[3] = falsearr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '李华'}]console.log(arr2) // [0, 2, '3', false, { name: '小帅'}]

2. 递归函数

    function deepClone(obj, hash = new WeakMap()) {if (obj === null) return nullif (obj instanceof Date) return new Date(obj) // 如果是日期对象,则直接返回一个新的日期对象if (obj instanceof RegExp) return new RegExp(obj) // 如果是正则对象,则直接返回一个新的正则对象// 如果循环引用了就用 weakMap 来解决  if (hash.has(obj)) return hash.get(obj);let allDesc = Object.getOwnPropertyDescriptors(obj);let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);hash.set(obj, cloneObj);for (let key of Reflect.ownKeys(obj)) {if (typeof obj[key] === 'object' && obj[key] !== null) {cloneObj[key] = deepClone(obj[key], hash); // 递归复制  } else {cloneObj[key] = obj[key];}}return cloneObj;}let arr1 = [1, 2, '3', true, { name: '李华' }, undefined]let arr2 = deepClone(arr1)arr2[4].name = '小帅'console.log(arr1) // [1, 2, '3', true, { name: '李华' }, undefined]console.log(arr2) // [1, 2, '3', true, { name: '小帅' }, undefined]

对象

一、浅拷贝

1. Object.assign()

    let obj1 = {a: 1, b: {c: 2}}let obj2 = Object.assign({}, obj1) // obj2={a:1, b: {c:2}}obj2.a = 100obj2.b.c = 200console.log(obj1) // { a: 1, b: { c: 200 } }console.log(obj2) // { a: 100, b: { c: 200 } }

2. 展开运算符…

    let obj1 = {a: 1, b: {c: 2}}let obj2 = {...obj1}obj2.a = 100obj2.b.c = 200console.log(obj1) // { a: 1, b: { c: 200 } }console.log(obj2) // { a: 100, b: { c: 200 } }

二、深拷贝

1. JSON方法

    let obj1 = {a: 1,b: {c: 2},d: [3, 4],e: undefined, // 注意此方法undefined不会被复制f: function(){ console.log('Hello world')} // 注意此方法函数不会被复制}let obj2 = JSON.parse(JSON.stringify(obj1))// console.log(obj2) // {a:1, b: {c:2}, d: [3,4]}obj2.b.c = 200obj2.d[0] = 300console.log(obj1) // { a: 1, b: { c: 2 }, d: [3, 4], e: undefined, f: f()}console.log(obj2) // { a: 1, b: { c: 200 }, d: [300, 4] }

2. 递归函数

    function deepClone(obj, hash = new WeakMap()) {// 处理基本数据类型和null  if (obj === null || typeof obj !== 'object') {return obj;}// 处理日期和正则对象  if (obj instanceof Date) {return new Date(obj);}if (obj instanceof RegExp) {return new RegExp(obj);}// 如果已经处理过这个对象,则直接返回缓存的结果  if (hash.has(obj)) {return hash.get(obj);}// 根据obj的类型创建一个新的对象或数组  let cloneObj = Array.isArray(obj) ? [] : {};hash.set(obj, cloneObj); // 将原始对象和克隆对象存储在hash中,以处理循环引用  // 递归复制对象的每个属性  for (let key in obj) {if (obj.hasOwnProperty(key)) {cloneObj[key] = deepClone(obj[key], hash);}}// 如果obj是Map或Set,则需要特殊处理  if (obj instanceof Map) {cloneObj = new Map();obj.forEach((value, key) => {cloneObj.set(deepClone(key, hash), deepClone(value, hash));});} else if (obj instanceof Set) {cloneObj = new Set();obj.forEach(value => {cloneObj.add(deepClone(value, hash));});}return cloneObj;}let obj1 = {a: 1,b: {c: 2},d: [3, 4],e: undefined, // 注意此方法undefined不会被复制f: function () { console.log('Hello world') } // 注意此方法函数不会被复制,而且其实通常不深拷贝函数}let obj2 = deepClone(obj1)// console.log(obj2) // { a: 1, b: { c: 2 }, d:[3, 4], e:undefined, f:f()}obj2.b.c = 200obj2.d[0] = 300console.log(obj1) // { a: 1, b: { c: 2 }, d: [3, 4], e: undefined, f: f()}console.log(obj2) // { a: 1, b: { c: 200 }, d: [300, 4], e: undefined, f: f() }

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词