JavaScript深浅克隆

426 阅读2分钟

基本概念

JavaScript数据分为简单的基本数据类型与复杂的引用类型;

  1. 简单数据类型:如(String,Number,Boolean,Undefined,Null)存储在栈里面;
  2. 复杂数据类型:如(Object,Array)地址存在栈里面,数据存储在堆里面;

JavaScript克隆分为浅克隆与深克隆;

  1. 浅克隆:原始类型为值传递,对象类型仍为引用传递,即当对一个对象或数组进行值的修改时会改变原始对象或数组的值行为;
  2. 深克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中,即党对一个对象或数组进行值的修改时不会改变原始对象或数组的值行为;

深浅克隆的实现

本篇仅对复杂的引用数据类型做记录

浅克隆

    //浅克隆
    const arr=["Rylan",18,"male"];
    const shallowCloneArr=arr;
    shallowCloneArr[1]=20;
    console.log(arr,shallowClone)
    //["Rylan",20,"male"],["Rylan",20,"male"]
    
    const obj={
        name:"Rylan",
        age:18,
        sex:"male"
    }
    const shallowCloneObj=obj;
    shallowCloneObj.age=20;
    console.log(obj,shallowCloneObj)
    //{name:"Rylan",age:20,sex:"male"},{name:"Rylan",age:20,sex:"male"}

从上面可以看出我们只修改了数据的副本,却连原始数据也都影响到了,这不符合我们的意愿;

深克隆

JSON.stringify()
    const arr=["Rylan",18,"male"];
    const arrJSON=JSON.stringify(arr);
    conset deepCloneArr=JSON.parse(arrJSON);
    deepCloneArr[1]=20;
    console.log(arr,deepCloneArr);
    //["Rylan",18,"male"],["Rylan",20,"male"]
    
    const obj={
        name:"Rylan",
        age:18,
        sex:"male"
    }
    const objJSON=JSON.stringify(obj);
    conset deepCloneObj=JSON.parse(objJSON);
    deepCloneObj.age=20;
    console.log(obj,deepCloneObj)
    //{name:"Rylan",age:18,sex:"male"},{name:"Rylan",age:20,sex:"male"}

嘿嘿~,使用深拷贝起来很简单有木有,但你要注意,使用JSON.stringify()方法需要你清楚JSON.stringify()需要注意的那九大特性,例如......,详情去看官网吧。

数组的结构赋值
    const arr=["Rylan",18,"male"];
    const deepCloneArr=[...arr];
    deepCloneArr[1]=20;
    console.log(arr,deepCloneArr);
    //["Rylan",18,"male"],["Rylan",20,"male"]
    
    const arr2=[{name:"Rylan"},{age:18},{sex:"male"}]
    const deepCloneArr2=[...arr2];
    deepCloneArr2[1]=20;
    console.log(arr2,deepCloneArr2);
    //[{name:"Rylan"},{age:18},{sex:"male"}]
    //[{name:"Rylan"},20,{sex:"male"}]

此方法适用于数组深拷贝;

数组与对象完整版
    function deepClone(data) { 
        let type=['string','number','boolean','undefined'];
        // 判断如果不是引用类型,直接返回数据即可 
        if (type.includes(typeof data)) { 
            return data 
        } else if (Array.isArray(data)) { 
            let arr = [];
            data.forEach(item => {
                arr.push(item)
            }) 
            return arr 
        } else if (typeof data === 'object') {
            var obj = {};
            for (let key in data) { 
                //递归
                obj[key] = deepClone(obj[key]) 
            } 
            return obj 
        } 
    }
    //数组
    const arr=[{name:"Rylan"},{age:18},{sex:"male"}];
    const arr2=deepClone(arr);
    arr2[1]=20;
    console.log(arr,arr2);
    //[{name:"Rylan"},{age:18},{sex:"male"}]
    //[{name:"Rylan"},20,{sex:"male"}]
    //对象
    const obj={name:"Rylan",age:18,sex:"male"};
    const obj2=deepClone(obj);
    obj2.age=20;
    console.log(obj,obj2);
    //{name:"Rylan",age:18,sex:"male"}
    //{name:"Rylan",age:20,sex:"male"}

此方法使用数组与对象的深克隆;

结尾

希望这篇文章在学习上可帮助各位小伙伴,在实际开发中提升开发效率,加深记忆......