js object深拷贝

javascript的传参都是引用传递。下面的代码

function mutate(obj) {
  obj.a = true;
}

const obj = {a: false};
mutate(obj)
console.log(obj.a);

答案:1: prints true 2: prints false

正确答案是1.因为这里正是通过引用来传参的。

那么下面这样是否可以呢?答案已经已经可以看到了,这里的Object.assign是一种浅拷贝,对于obj里面还有嵌套的对象时,一样存在引用传递的问题

const obj = /* ... */;
const copy = Object.assign({}, obj);
function mutateDeepObject(obj) {
  obj.a.thing = true;
}

const obj = {a: {thing: false}};
const copy = Object.assign({}, obj);
mutateDeepObject(copy)
console.log(obj.a.thing); // prints true

还有object.spread同样是创建一个浅拷贝

当然,有时你可能想要完全拷贝一个对象,作为参数去传递,从而不影响原有的对象。下面是介绍几种深拷贝的例子

1,json.parse

const obj = /* ... */;
const copy = JSON.parse(JSON.stringify(obj));

怎么样,可能你曾用过,这里就是深拷贝的引用。

但是对Maps, Sets, RegExps, Dates, ArrayBuffers等不适用。

  1. MessageChannel
function structuralClone(obj) {
  return new Promise(resolve => {
    const {port1, port2} = new MessageChannel();
    port2.onmessage = ev => resolve(ev.data);
    port1.postMessage(obj);
  });
}

const obj = /* ... */;
const clone = await structuralClone(obj);

这里的消息对象 obj接收方就是一个深拷贝对象.这里是一种异步深拷贝。下面的state则是同步深拷贝的应用

3.History API

function structuralClone(obj) {
  const oldState = history.state;
  history.replaceState(obj, document.title);
  const copy = history.state;
  history.replaceState(oldState, document.title);
  return copy;
}

const obj = /* ... */;
const clone = structuralClone(obj);

这里的 state每次都是一次深拷贝.(safari限制30ms内最多调用100次)

4.Notification API

function structuralClone(obj) {
  return new Notification('', {data: obj, silent: true}).data;
}

const obj = /* ... */;
const clone = structuralClone(obj);

这种方式受浏览器权限限制,会比较慢。由于某些原因safari会返回 undefined

总结:实际中使用时,可以优先使用
1,JSON.parse(JSON.stringify())性能最佳且各支持种浏览器
2.MessageChanne 支持各种浏览器

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值