在JavaScript中如何拷贝一个对象?

通过引用调用

function mutate(obj) {obj.a = true;
}
const obj = {a: false};
mutate(obj)
console.log(obj.a); // prints true

mutate可以对obj进行改动,然后外面的obj的值也变化了。

浅拷贝:Object.assign()

一种拷贝方式是这种方法: Object.assign(target, sources...).

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

JSON.parse

通过转换为字符串,然后再转回来:

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

这样不好的地方是你会处理一个大的字符串,并且无法处理
循环对象:

const x = {};
const y = {x};
x.y = y; // Cycle: x.y.x.y.x.y.x.y.x...
const copy = JSON.parse(JSON.stringify(x)); // throws!

而且像Maps, Sets, RegExps, Dates, ArrayBuffers和其他内置对象序列化的时候可能都有问题。

结构化克隆

它是一种算法,将一个值转换为另外一个值。而且能处理对象循环依赖和大部分的内置对象。比如调用postMessage发消息给window或者WebWorker的时候就用到。
比如像这样:obj是被深拷贝过的

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);

历史API

如果你用过history.pushState()去构建一个单页应用(SPA),你应该知道你可以根据当前URL保存一个state object。这个state object是结构化拷贝的,并且是同步的。

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);

不好的地方是Safari限制replaceState的调用次数。

通知API

function structuralClone(obj) {return new Notification('', {data: obj, silent: true}).data;
}
const obj = /* ... */;
const clone = structuralClone(obj);

性能如何




结论是:
1 如果你不处理对象依赖和内置对象,可以直接用 JSON.parse(JSON.stringify())

2 如果你要可靠的跨浏览器支持:用MessageChannel

原文:
https://dassur.ma/things/deep-copy/#call-by-reference

作者知乎/公众号:前端疯

转载于:https://www.cnblogs.com/xunxing/p/a255ce21d8d85939ec4ce56def8cc0b0.html

(译文)JavaScript基础——JavaScript中的深拷贝相关推荐

  1. VN-SGG JavaScript 基础(中)

    [VN-SGG] JavaScript 基础(中) JavaScript视频课程笔记[入门到精通],这只是笔记!!! 主要内容: this,对象,原型对象,垃圾回收,数组: call.apply,ar ...

  2. JavaScript基础函数体中的唯一var模式(002)

    全局变量是不好的.所以在声名变量的时候,应该采用函数体中的唯一var模式(Single var Pattern).这个模式有不少好处: 提供了一个唯一的地方来查看函数体中声名的变量 在使用一个变量之前 ...

  3. JavaScript基础: DOM中操作属性以及自定义属性

    上一篇聊了一些常用的事件以及演示其如何使用,演示的时候发现一件事情,那就是DOM操作不单是得到元素,还可以修改元素的属性.现在开始如何操作其属性. 普通自带的属性 这些属性是某些标签自带的属性比如sr ...

  4. JavaScript基础JavaScript的常用编码惯例(007)

    采用一定的编码惯例,可以使得项目中的代码提到较高的一致性,可读性和可预测性. 1.缩进 缩 进可以提高代码的可读性.不过错误的缩进也可能导致代码的误读.有人认为缩进应该使用tab,另外的一些人主张采用 ...

  5. JavaScript基础笔记

    今日内容 1. JavaScript基础 JavaScript: * 概念: 一门客户端脚本语言* 运行在客户端浏览器中的.每一个浏览器都有JavaScript的解析引擎* 脚本语言:不需要编译,直接 ...

  6. Web前端之JavaScript基础

    Web前端之JavaScript基础 JavaScript介绍 变量 变量类型 基本的数据类型Number String Boolean underfined null typeof运算符 引用的数据 ...

  7. JavaScript-百炼成仙(第1节掌握JavaScript基础1.1-1.21)

    文章目录 1.1 第一章 初入宗门 1.2 第二章 直接量 1.3 第三章 数据类型 1.4 第四章 数据类型 扩展内容: 1.5 第五章 基础考核 1.6 第六章 何老 1.7 第七章 对象数据类型 ...

  8. javascript百炼成仙 第一章 掌握JavaScript基础 1.12 JavaScript运算符

    题目一出,真是几家欢喜几家愁,那些复习得好的,自然可以款款而谈,可是那些本身基础就薄弱的弟子,立刻尴尬地说不出话来.甚至有的弟子已经举双手表示要放弃比赛.这些举动立刻引来了场外那些大弟子的哄笑.尤其是 ...

  9. JavaScript基础之基础

    JavaScript基础 JavaScript简介 一个完整的JavaScript实现应该由以下三个部分构成: ECMAScript 标准 DOM 文档对象模型 BOM 浏览器对象模型 JS也是一种面 ...

最新文章

  1. 洛谷3384:【模板】树链剖分——题解
  2. 要学习的别人的博客网址---收藏
  3. alpine运行程序提示not found
  4. C Tester Doer Pattern
  5. 【uoj#225】[UR #15]奥林匹克五子棋 构造
  6. Android Linker学习笔记
  7. Algorithm, Secret key and Protocol
  8. Xamarin中国峰会2019
  9. [css] 移动端页面不满一屏时如何实现满屏背景?
  10. CodeVS 1068-乌龟棋
  11. Kali Linux Web 渗透测试秘籍 第二章 侦查
  12. 计算机辐射有那些预防措施,冰箱辐射有多大 冰箱辐射防范措施
  13. 设置时间同步(ntp)详细步骤
  14. openwrt运行linux软件,使用OpenWrt开发嵌入式Linux(二):先让系统跑起来(使用initramfs)...
  15. 第十一章 Caché 命令大全 HALT 命令
  16. Sentiment Classification towards Question-Answering with Hierarchical Matching Network 论文阅读笔记
  17. element-ui走马灯使用心得
  18. Python对遥感影像重采样,以及重采样方法
  19. win10系统重装(无需u盘)(无需下载第三方软件)(绝对纯净版)(全网最简)
  20. 【Python机器学习基础教程】(三)

热门文章

  1. java传参怎么理解_如何理解Java的值传递
  2. SpringBoot的email发送ssl协议格式
  3. sed搜索某行在行末追加_linux shell 用sed命令在文本的行尾或行首添加字符
  4. 达标率用计算机怎么算,达标率怎么算
  5. Oracle 分页查询语句SQL
  6. 虚拟机的分类_虚拟化精华问答 | 虚拟化技术分类
  7. 画师id_100位插画师是怎么过日子的?
  8. 虚拟局域网vlan实验报告_自动化已非原来的自动化:看虚拟局域网技术应用到罗克韦尔的DCS...
  9. 用shell获取mysql主从状态_shell监控MySQL主从状态脚本两则
  10. oracle 查看并行数据库,Oracle数据库并行查询出错的解决方法