详谈JavaScript深浅拷贝

详谈JavaScript深浅拷贝

为什么?

什么是拷贝:复杂粘贴
为什么分深浅拷贝:

  • JavaScript里面的数据存储分为两种:
    • 简单数据类型:存储在栈里面
    • 复杂数据类型:地址存在栈里面,数据存储在堆里面
  • 而复杂粘贴是在操作栈里面的数据

需要使用的数据:

let obj = {
    name: 'JavaScript',
    age: 25,
    type: [
        '弱类型',
        '解释型',
        '脚本语言'
    ]
}

回到顶部 目录

浅拷贝

第一种方式:利用循环的方式

let copyObj = {};

// 浅拷贝
for(const key in obj){
    copyObj[key] = obj[key]
}

第二种方式:利用Object.assign

let copyObj = {};

// 浅拷贝
// 第一个参数是目标对象 copyObj
// 其他参数都为拷贝对象 obj
Object.assign(copyObj, obj)

修改copyObj对象看obj有什么变化:

// 图一
console.log('obj', obj);
console.log('copyObj', copyObj);

copyObj.name = 'Python';    // 没有影响
copyObj.type.push('脚本语言');  // 有影响
copyObj.eat = false;    // 没有影响

// 图二
console.log('obj', obj);
console.log('copyObj', copyObj);

图一
图二

分析:

  • 浅拷贝:其实拷贝的是栈里面的内容(name没有发生改变,而type同时发生修改了)
  • 对于没有复杂类型的数据就可以采用此方法

回到顶部 目录

深拷贝

第一种方法:JSON.parse(JSON.stringify())

let copyObj = {};

copyObj = JSON.parse(JSON.stringify(obj));
  • 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝

第二种方法:自定义方法来实现:deepCodeObjec

let copyObj = {};

function deepCodeObjec(fromObj){
    let toObj;
    // 在函数中先检查第一个参数是否有值
    // 如果没有直接返回一个空对象
    if (checkedType(fromObj) === 'Object') {
        toObj = {};
    } else if (checkedType(fromObj) === 'Array') {
        toObj = [];
    } else {
        return fromObj;
    }

    for(const key in fromObj){
        let fromValue = fromObj[key];

        if(checkedType(fromValue) === 'Object' || checkedType(fromValue) === 'Array'){  // 如果是复杂类型就递归调用,再来一次
            toObj[key] = deepCodeObjec(fromValue);
        }else{  // 如果不是就自己复制
            toObj[key] = fromValue;
            
        }
    }
    
    return toObj;
}

// 定义检查数据类型的功能函数
function checkedType(param) {  
    return Object.prototype.toString.call(param).slice(8, -1);
}

copyObj = deepCodeObjec(obj);
  • 递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

修改copyObj对象看obj有什么变化:

copyObj.name = 'Python';    // 没有影响
copyObj.type.push('脚本语言');  // 没有影响

console.log('obj', obj);
console.log('copyObj', copyObj);

图一

图四

分析:

  • JSON.parse(JSON.stringify()):这种方法虽然可以实现数组或对象深拷贝,但不能处理函数。
    图三

回到顶部 目录

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值