zoukankan      html  css  js  c++  java
  • js之浅拷贝与深拷贝


    • 浅拷贝:只会复制对象的第一层数据
    • 深拷贝:不仅仅会复制第一层的数据,如果里面还有对象,会继续进行复制,直到复制到全是基本数据类型为止

    简单来说,浅拷贝是都指向同一块内存区块,而深拷贝则是另外开辟了一块区域

    例如,下面就是浅拷贝:

    
    let arr = [1,2,3,4];
    let arr2 = arr;
    
    arr2.push(5);
    
    console.log(arr); // [1, 2, 3, 4, 5]
    console.log(arr2); // [1, 2, 3, 4, 5]
    

    对深拷贝来说,有以下的方法:

    1. 深拷贝的简单方法:

    • 对数组来说:
    let arr = [1,2,3,4];
    
    let arr2 = [];
    
    for(let i=0;i<arr.length;i++){
        arr2[i] = arr[i];
    }
    
    arr2.push(5);
    
    console.log(arr); // [1, 2, 3, 4]
    console.log(arr2); // [1, 2, 3, 4, 5]
    
    • 对对象来说(for..in):
    let obj = {
        name:"haha",
        age:18
    }
    
    let obj2 = {};
    
    for(var attr in obj){
        obj2[attr] = obj[attr]
    }
    
    obj2.name = 'hehe';
    
    console.log(obj); // {name: "haha", age: 18}
    console.log(obj2); // {name: "hehe", age: 18}
    

    2. 转成 JSON 再转回来

    JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。

    let arr = [1,2,3,4];
    let arr2 = JSON.parse(JSON.stringify(arr));
    
    // JSON.parse()	用于将一个 JSON 字符串转换为 JavaScript 对象。
    // JSON.stringify()	用于将 JavaScript 值转换为 JSON 字符串。
    
    arr2.push(5);
    
    console.log(arr); // [1, 2, 3, 4, 5]
    console.log(arr2); // [1, 2, 3, 4, 5]
    

    3. 深拷贝的es6方法:Object.assign()

    let obj = {
        name:"haha",
        age:18
    }
    
    let obj2 = {};
    
    Object.assign(obj2,obj);
    
    obj2.name = 'hehe';
    
    console.log(obj); // {name: "haha", age: 18}
    console.log(obj2); // {name: "hehe", age: 18}
    

    4. 深拷贝的方法封装:

    但是,对于下面的例子(包含多层对象),不能用Object.assign()

    let arr = [1,2,3,4,[5],{}];
    
    let arr2 = Object.assign([],arr);
    
    arr2[4].push(6);
    
    console.log(arr) // [1, 2, 3, 4, [5,6], {…}]
    console.log(arr2) // [1, 2, 3, 4, [5,6], {…}]
    

    所以,这里封装了一个深拷贝函数deepClone

    let arr = [1,2,3,4,[5],{}];
    
    let arr2 = deepClone(arr);
    
    arr2[4].push(6);
    
    function deepClone(obj){ //深度克隆
        let o = obj.push?[]:{};
        for(let attr in obj){
            //值为复合类型
            if(typeof obj[attr] === 'object' && obj[attr]!=null){
                o[attr] = deepClone(obj[attr]);
            }else{
                o[attr] = obj[attr];
            }  
        }
        return o;
    }
    
    console.log(arr) // [1, 2, 3, 4, [5], {…}]
    console.log(arr2) // [1, 2, 3, 4, [5,6], {…}]
    
  • 相关阅读:
    jQuery实现鼠标点击Div区域外隐藏Div
    JS判断输入值为正整数
    trim()不兼容ie的问题及解决方法
    傻问题就用傻办法:解决问题有时候不需要探究根源,依据表象就能直接解决
    /vendor/lib64/libOpenCL.so在安卓应用中无访问权限的解决办法
    复数域上的人工神经网络与量子计算
    中国移动CMCC家庭路由器的默认登陆账号
    717. 1-bit and 2-bit Characters
    219. Contains Duplicate II
    1346. Check If N and Its Double Exist
  • 原文地址:https://www.cnblogs.com/cckui/p/8078971.html
Copyright © 2011-2022 走看看