深入剖析 JavaScript 的深浅拷贝

let a = {
    age: 1
}
let b = a
a.age = 2
console.log(b.age) // 2

从上述例子中我们可以发现,如果给一个变量赋值一个对象,那么两者的值会是同一个引用,其中一方改变,另一方也会相应改变。

通常在开发中我们不希望出现这样的问题,我们可以使用浅拷贝来解决这个问题。

浅拷贝:

1、使用 Object.assign 

let a = {
    age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(b.age) // 1

2、使用展开运算符(…)

let a = {
    age: 1
}
let b = {...a}
a.age = 2
console.log(b.age) // 1

通常浅拷贝就能解决大部分问题了,但是当我们遇到如下情况就需要使用到深拷贝了。

let a = {
    age: 1,
    jobs: {
        first: 'FE'
    }
}
let b = {...a}
a.jobs.first = 'native'
console.log(b.jobs.first) // native

浅拷贝只解决了第一层的问题,如果接下去的值中还有对象的话,那么就又回到刚开始的话题了,两者享有相同的引用。要解决这个问题,我们需要引入深拷贝。

深拷贝:

1.纯 JSON 数据对象:使用 JSON 全局对象的 parse 和 stringify 方法。

缺点:不能拷贝函数,并且会丢失原型链。

//JSON.stringify()将对象转成字符串;JSON.parse()将字符串转成对象
let a = { x: 10, y: [20, 5]}

let b = JSON.parse(JSON.stringify(a))

2.jQuery —— $.clone() / $.extend()

   $.clone() :用于 DOM 对象的深复制。

 $.extend():用于JS 对象的深复制。在 jQuery 中可以通过添加一个参数来实现递归extend。调用$.extend(true, {}, ...)就可以实现深复制。

//改变y,z中的属性值不会修改原对象
var x = {
    a: 1,
    b: { f: { g: 1 } },
    c: [ 1, 2, 3 ]
};

var y = $.extend({}, x),          //shallow copy
    z = $.extend(true, {}, x);    //deep copy  深拷贝

y.b.f === x.b.f       // true  
z.b.f === x.b.f       // false

y.a=2;
x.a;//1
z.a=3;
x.a;//1

​

3.ES6中的新方法:Object.create()生成操作Object.isPrototypeOf读操作

 克隆原始对象自身的值,且保持继承链来克隆它继承的值。

let m1={
    a: 1,
    b: { f: { g: 1 } },
    c: [ 1, 2, 3 ]
};

let n = Object.getPrototypeOf(m);//读取m的原型属性方法
let m2= Object.assign(Object.create(n), origin);//Object.create(n)创建一个新对象{}并继承原对象的原型属性方法

m2.b.f===m1.b.f;//false
m2.a=2;
m1.a;//1

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值