JS基础:深拷贝和浅拷贝

一、对于基本数据类型(Number,String, Boolean....)来说,与其说是深拷贝,严格来说,它们叫做赋值。

let a = 5;
let b = a;
b = 3;
console.log(a, b); // 5 3

二、对于引用数据类型(Object,Array)的深浅拷贝有很多方法,我们依次来看一下:

1. 直接通过赋值,然后进行修改,结果是浅拷贝。

// 数组与对象的赋值,都叫做浅拷贝
let arr = [1, 2, 3];
let newArr = arr;
newArr.push(4);
console.log(arr, newArr);

        

2. 使用数组解构进行拷贝:分为两种情况:

     情况一:对一维数组使用解构,进行拷贝,结果是深拷贝

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

 

     情况二:对多维数组使用解构,进行拷贝,结果是浅拷贝

let arr = [[1, 2, 3], [4, 5, 6]];
let newArr = [...arr];
newArr[0].push(4);
console.log(arr, newArr);

  
3. 使用JSON.Parse(JSON.stringify()),实现深拷贝

        先将一个JavaScript对象转为一个JSON字符串,再转化为JSON对象。

let list = [
    { id: 1, name: '张三' },
    { id: 2, name: '李四' },
    { id: 3, name: '王五' },
]
let newList = JSON.parse(JSON.stringify(list));
newList.push({ id: 4, name: '兜兜' });
console.log(list, newList);

  

三. 实现深拷贝的Function函数

写法一:

let objc = {
    name: '张三', // 基本数据类型
    age: 18, // 基本数据类型
    objInfo: { // 引用数据类型:Object
        sex: '女',
        hobby: '游泳'
    },
    arr: [1, 2, 3] // 引用数据类型: Array
}

function deepClone(info) {
    // 数组的constructor会指向Array() { [natice code] }
    // 对象的constructor会指向Object() { [native code] }
    const targetInfo = info.constructor === Array ? [] : {};
    // for in 即可以遍历对象,也可以遍历数组
    for (let keys in info) {
        if (info.hasOwnProperty(keys)) {
            // keys可能有三种类型:基本数据类型, Object, Array
            // 如果是引用数据类型
            if (info[keys] && typeof info[keys] === 'object') {
                // 这行可写可不写
                // targetInfo[keys] = info[keys].constructor === Array ? [] : {};
                // 递归
                targetInfo[keys] = deepClone(info[keys])
            } else { // 如果是基本数据类型
                targetInfo[keys] = info[keys];
            }
         }
     }
     return targetInfo
}

let newObj = deepClone(objc)
newObj.name = '李四'
newObj.arr.push('打豆豆')
console.log(objc, newObj);

写法二:

let obj = {
    name: '穗穗',
    age: 18,
    info: {
         sex: '女',
         height: 162
    },
    arr: [1,2,3]
}
const obj1 = deepClone(obj)

function deepClone(info) {
    // 判断info的数据类型,如果是基本数据类型或为赋值,直接返回
    // 如果info未赋值 ==> let info; info=undefined
    //  info == null 相当于if (info === null || info === undefined)
    //  info == null为true,info === null为false,所以此处用==
    if (typeof info !== 'object' || info == null) {
        return info;
    }
    let resultObj;
    if (info instanceof Array) {
        resultObj = []
    } else resultObj = {};
    for (let key in info) {
        if (info.hasOwnProperty(key)) {
            resultObj[key] = deepClone(resultObj[key])
        }
    }
    return resultObj
}

还有另一种更简单的实现深拷贝的Function函数;

// 深拷贝函数
function deepClone(obj) {
    // 1 判断是否是非应用类型或者null
    if (typeof obj !== 'object' || obj == null) return obj
    // 2 创建一个容器
    let cloneObj = new obj.constructor()
    // 3 拿到对象的keys,给容器赋值
    Object.keys(obj).forEach(v => cloneObj[v] = deepClone(obj[v]))
    // 4 返回容器
    return cloneObj
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值