js数组拷贝

作者: 阿蒙 时间: 2023-12-16 标签: JavaScript 浏览: 1901 评论: 0

    所谓深浅拷贝是针对引用类型的区别。 基础类型是值传递,存储在栈中。 引用类型引用存储在栈中,值存储在堆中。所以基本类型的值是不可改变的,使用赋值操作符时其实是生成一个新的基础类型。 而引用类型使用赋值时,只是重新生成了栈中的引用,而引用对于的值还是相同的。

     所以引用类型拷贝需要将属性进行递归遍历,直至属性为基础类型时进行拷贝。 否则就是浅拷贝,浅拷贝时修改新对象的值会同时修改到旧对象的值。 

     综上所述,浅拷贝很简单,直接{...oldObj}。 或者 Object.assign({}, oldObj) 等方法即可。而深拷贝则需要递归属性进行判断。 (有个简便方法,即JSON.stringify()。 此方法将对象转为了字符串进行赋值,所以也能实现深拷贝。但是转为字符串时 function ,undefined的属性会丢失)

1、为基础类型,直接进行赋值操作。

2、为对象,进行递归调用判断

3、为数组,如果数组中为基础类型,使用slice生成一个新对象,或者解构运算符[...arr]。 如果数组含有引用类型则需要遍历属性至基础类型进行操作。

4、 为set, 直接new Set ([..oldSet])即可。

5、 为set, 直接new Map([..oldMap])即可。

6、为symbol, 为symbol 进行1的操作即可。前提是访问到symbol,可以使用Object.getOwnPropertySymbols()访问对象的symbol。然后遍历赋值给克隆对象

7、函数,可以考虑转成字符串之后进行处理

8 、其他等等 可以根据实际需求进行扩展相应方法。   

示例代码如下:  

const cloneBase = (newData, oldValue, key) => {
 newData[key] = oldValue;
}
cont cloneArr = (newData, oldValue, key) => {
 // 这里假定数组内部只有基础类型
 newData[key] =oldValue.slice(0);
}
const cloneSet = (newData, oldValue, key) => {
 newData[key] = new Set([...oldValue]);
}
const cloneMap = (newData, oldValue, key) => {
 newData[key] = new Map([...oldValue]);
}
// 其他依次按照步骤写相应的方法

function deepCopy(data) => {
 if (typeof !== "object") {
  // 如果为基础类型则直接返回基础类型、这里没有处理symbol
  return data;
 }
 let new Data = {};
 Object.keys(data).forEach(key => {
   const curr = data[key];
  // 如果为基础类型
  if (typeof curr !== "object") {
    cloneBase(newData, curr, key);
   }
  // 其他依次调用判断方法即可,最后如果处理对对象进行递归调用处理
  else {
   newData[key] = deepCopy(curr);
  }
 });
  return new Data();
 }
0

本文相关标签: 原生JS

赞助商

发表评论: