美文网首页
js深拷贝

js深拷贝

作者: 香蕉不拿呢 | 来源:发表于2021-12-31 09:50 被阅读0次

    在写深拷贝之前,有必要说一下js的数据类型

    一.js数据类型
    1.1 分类

    js数据类型分为两类:原始数据类型、引用数据类型
    原始数据类型:string,number,boolean,null,undefined,symbol
    引用数据类型:function,array,object等

    1.2 区别

    原始数据类型存储在栈内存中,引用数据类型存储在堆内存中。
    原始数据类型存储的数据是值,引用数据类型存储的数据是空间地址。

    1.3 赋值

    原始数据类型赋值时是直接赋值数值。修改原数据不会影响新变量。
    引用数据类型赋值时是赋值空间地址。修改原数据有可能会影响新变量

    let str = "banana"
    let str2 = str
    str2 = "apple"
    // str == "banana" str2 == "apple"
    
    let obj = { name : "banana" }
    let obj2 = obj
    obj2.name = "apple"
    // obj.name == "apple"
    
    二.数据深拷贝

    引用数据类型赋值时赋值的是空间地址,修改原数据会影响新变量,这时候就需要用到深拷贝。

    2.1 JSON(不考虑引用类型)

    使用json的方法实现深拷贝

    JSON.parse(JSON.stringify(obj))
    
    2.2 递归(不考虑引用类型)
    function deepClone(obj){
        // 判断是引用类型还是原始类型
        if(typeof obj === "object" && obj !== null){
            // 判断是数组还是对象类型
            let newObj = Array.isArray(obj)?[]:{}
            for(let key in obj){
              newObj[key] = deepClone(obj[key])
            }
            return newObj
        }else{
            return obj
        }
    }
    
    2.3 考虑引用类型
    function foo3(target,map = new Map()){
        if(target === null || typeof target !=='object')return target;
        let constructor = target.constructor;
        if(/^(Function|Date|Map|Set|RegExp)$/i.test(constructor.name)){
            return new constructor(target)
        }
        if(map.get(target))return map.get(target);
        map.set(target,true);
        let res = Array.isArray(target) ? [] : {}
        for(let key in target){
            res[key] = foo3(target[key],map)
        }
        return res
    }
    

    相关文章

      网友评论

          本文标题:js深拷贝

          本文链接:https://www.haomeiwen.com/subject/htrgqrtx.html