js 数组浅拷贝和深拷贝

173 阅读1分钟

浅拷贝

  1. 普通一维数组

    直接赋值

    const a = [1, 2, 3];
    const b = a; 
    a[0] = 0;
    console.log(a); // [0, 2, 3]
    console.log(b); // [0, 2, 3]
    
  2. 对象一维数组

    直接赋值

    const a = [{ name: "zjx" }];
    const b = a; 
    a[0].name = 'zjx2';
    console.log(a); // [{ name: "zjx2" }]
    console.log(b); // [{ name: "zjx2" }]
    

    循环遍历

    function shallowCopy(obj) {
      if (typeof obj !== 'object') return;
      const newObj = [];
      for(let key in obj) {
        if (obj.hasOwnProperty(key)) {
          newObj[key] = obj[key];
        }
      }
      return newObj;
    }
    const a = [{name:'zjx'}];
    const b = shallowCopy(a);
    a[0].name = 'zjx2';
    console.log(a); // [{name: "zjx2"}]
    console.log(b); // [{name: "zjx2"}]
    
    const a = [{name:'zjx'},1];
    const b = deepCopy(a);
    function deepCopy(arr) {
        let newArr = [];
        for (let i = 0; i < a.length; i++) {
         newArr.push(arr[i]);
        }
        return newArr;
    };
    a[0].name= 'zjx2'; 
    a[1]=2;
    console.log(a); // [{name:'zjx2'}, 2]
    console.log(b); // [{name:'zjx2'}, 1]
    

    ES6 扩展运算符

    const a = [{ name: "zjx" }];
    const b = [...a]; 
    a[0].name = 'zjx2';
    console.log(a); // [{ name: "zjx2" }]
    console.log(b); // [{ name: "zjx2" }]
    

深拷贝

  1. 普通一维数组

    slice 方法

    const a = [1, 2, 3];
    const b = a.slice(0); 
    a[0] = 0;
    console.log(a); // [0, 2, 3]
    console.log(b); // [1, 2, 3]
    

    concat 方法

    const a = [1, 2, 3];
    const b = a.concat(); 
    a[0] = 0;
    console.log(a); // [0, 2, 3]
    console.log(b); // [1, 2, 3]
    

    map 方法

    const a = [1, 2, 3, 4];
    const b = a.map(function (value) { // 使用 map 方法遍历数组然后返回新的数组
      return value;
    }); 
    a[0] = 0;
    console.log(b[0]); // 1
    console.log(a); // [0, 2, 3, 4]
    console.log(b); // [1, 2, 3, 4]
    

    ES6 扩展运算符

    const a = [1, 2, 3, 4];
    const b = [...a]; 
    a[0] = 6;
    console.log(b[0]); // 1
    console.log(a); // [6, 2, 3, 4]
    console.log(b); // [1, 2, 3, 4]
    

    循环遍历

    const a = [1,2,3];
    const b = deepCopy(a);
    function deepCopy(arr) {
        let newArr = [];
        for (let i = 0; i < a.length; i++) {
         newArr.push(arr[i])
        }
        return newArr;
    };
    a[0]=0; 
    console.log(a); // [0, 2, 3]
    console.log(b); // [1, 2, 3]
    
  2. 对象一维数组

    JSON.stringify() 方法

    只限于处理可被 JSON.stringify() 编码的值,包含 Boolean Number String 对象 数组。其他任何内容都将被特殊处理。Function Symbol Infinity undefined NaN 会变成 null,Date 对象会被转化为 String,可以调用 toISOString() 方法将其转为字符串。

    const a = [{ name: "zhangsan", age: 1 }, { name: "lisi", age: 2 }, 1, undefined, NaN, new Date(), new Date().toISOString(), function test() {}, Symbol("0")];
    const b = JSON.parse(JSON.stringify(a));
    a[1].age = 3;
    a[2] = 2;
    console.log(a, b); 
    

    map 方法

    const a = [{ name: "zhangsan", age: 1 }, { name: "lisi", age: 2 }];
    const b = a.map((val) => ({ ...val }));
    a[1].age = 3;
    a[2] = 2;
    console.log(a); // [{ name: "zhangsan", age: 1 }, { name: "lisi", age: 3 }, 2]
    console.log(b); // [{ name: "zhangsan", age: 1 }, { name: "lisi", age: 2 }]
    

    循环递归调用(适用于对象和数组)

    function deepCopy(obj) {
      if (typeof obj !== 'object') return;
      const newObj = obj instanceof Array ? [] : {}; 
      for(let key in obj) {
        if (obj.hasOwnProperty(key)) {
          newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
      }
      return newObj;
    }; 
    // 数组拷贝
    const a = [{name:'zjx'},1];
    const b = deepCopy(a);
    a[0].name='zjx2'; 
    a[1] = 2;
    // 对象拷贝
    const c= {age:1};
    const d = deepCopy(c); 
    c.age = 2;
    console.log(a); // [{name:'zjx2'}, 2]
    console.log(b); // [{name:'zjx'}, 1]
    console.log(c); // {age: 2}
    console.log(d); // {age: 1}
    
    function deepCopy(target) {
        if (typeof target === 'object') {
            let cloneTarget = Array.isArray(target) ? [] : {};
            for (const key in target) {
                cloneTarget[key] = deepCopy(target[key]);
            }
            return cloneTarget;
        } else {
            return target;
        }
    };
    const a = [{name:'zjx'},1];
    const b = deepCopy(a);
    a[0].name='zjx2';
    a[1]=2; 
    const c= {age:1};
    const d = deepCopy(c); 
    c.age = 2;
    console.log(a); // [{name:'zjx2'}, 2]
    console.log(b); // [{name:'zjx'}, 1]
    console.log(c); // {age: 2}
    console.log(d); // {age: 1}