js深浅拷贝浅谈

js中的数据可以分为基础数据类型和引用数据类型。基础数据类型(undefinded,null,Number,String,Boolean,symbol)的数据存放在栈中;引用数据类型存放在堆中,栈中存放的是堆中的引用地址。
深浅拷贝的区别:
浅拷贝:将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
深拷贝:创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
浅拷贝与赋值
首先要明确浅拷贝不等于赋值。对于引用数据类型中数据都是基本数据类型时浅拷贝得到的值和复制得到的相同,改变其中之一也都不会影响另外一个,但是两者的本质不同。浅拷贝会在堆中重新开辟空间存放数据,而赋值只是单纯地保存被拷贝的对象的引用地址。用代码展示如下

let a = [1,{a: 1, b:{aa:11}}]
let b = a.slice()
let c = a
console.log(c === a) // true
console.log(b === a) // false

浅拷贝只会对第一层数据做处理,对于更深层级的数据只是单纯的复制引用(Array.slice Array.concat Object.assign)

let a = [1,{a: 1, b:{aa:11}}]
let b = a.slice() // [1,{a:1, b:{aa:11}}]
b[0] = 2
b[1].b.aa = 3;
b[1].a = 12
console.log(b) // [2,{a:12, b:{aa:3}}]
console.log(a) // [1,{a:12, b:{aa:3}}]
// Object.assign()
var obj1 = {a: 1, b: 2}
var obj2 = {A: 1, B: {C:3}}
var Coll = Object.assign({},obj1,obj2)
obj1.a = 11
obj2.B.C = 33
console.log(obj1) // { a: 11, b: 2 }
console.log(obj2) // { A: 1, B: { C: 33 } }
console.log(Coll) // { a: 1, b: 2, A: 1, B: { C: 33 } }

深拷贝:对所有的属性值都会做一次拷贝赋值,最常见的实现方式:递归

function deepClone(source) {
    let target = source.constructor === Array ? [] : {};
    for (let key in source) {
        if (source.hasOwnProperty(key)) {
            if (source[key] && typeof source[key] === 'object') { //判断第二层是否也是一个对象,若是则递归
                target[key] = source[key].constructor === Array ? [] : {};
                target[key] = deepClone(source[key])
            } else { // 第二层数据是基本是类型则直接赋值
                target[key] = source[key]
            }
        }
    }
    return target;
}

深拷贝实现方式之偏门:JSON.stringify() 将对象转成JSON字符串,再用JSON.parse() 将字符串转成JSON对象。
缺点:会抛弃对象的constructor,也就是深复制之后,无论这个对象原本的构造函数是什么,在深复制之后都会变成Object。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值