当前位置:首页 > 科技  > 软件

JS 中如何克隆对象?你学会了吗?

来源: 责编: 时间:2024-01-08 09:17:57 311观看
导读大家好,这里是大家的林语冰。JS 中如何克隆对象?此问题看似简单,实际十分复杂。假设我们需要获取下述对象的拷贝。const cat = { name: '薛定谔', girlFriends: { name: '龙猫' }}我们应该简单地创建一个新变量吗?(不)如

大家好,这里是大家的林语冰。6dF28资讯网——每日最新资讯28at.com

JS 中如何克隆对象?此问题看似简单,实际十分复杂。6dF28资讯网——每日最新资讯28at.com

假设我们需要获取下述对象的拷贝。6dF28资讯网——每日最新资讯28at.com

const cat = {  name: '薛定谔',  girlFriends: { name: '龙猫' }}

我们应该简单地创建一个新变量吗?(不)

如果我们将对象赋值给一个新变量,那几乎毫无卵用。6dF28资讯网——每日最新资讯28at.com

const newCar = catnewCat.name = '柴郡猫'console.log(newCat.name) //=> 柴郡猫console.log(cat.name) //=> 柴郡猫

两个对象都会变化。6dF28资讯网——每日最新资讯28at.com

原因很简单 —— 我们并没有创建一个新对象。我们只是创建了一个新的引用。6dF28资讯网——每日最新资讯28at.com

现在有两个变量:cat 和 newCat,它们都引用同一个对象。6dF28资讯网——每日最新资讯28at.com

浅克隆

何时浅克隆:当我们的对象属性有且仅有一层深度,或者我们不关心嵌套引用时。6dF28资讯网——每日最新资讯28at.com

当且仅当源对象不包含对其他对象的任何引用时,浅克隆才有效。6dF28资讯网——每日最新资讯28at.com

const newCat = { ...cat }newCar.name = '柴郡猫'console.log(newCat.name) //=> 柴郡猫console.log(cat.name) //=> 薛定谔newCat.girlFriends.name = '加菲猫'console.log(newCat.girlFriends.name) //=> 加菲猫console.log(cat.girlFriends.name) //=> 加菲猫

更新女友名字也会导致原始名字变化,这是因为 newCat.girlFriends 和 car.girlFriends 仍然引用内存中的同一对象。6dF28资讯网——每日最新资讯28at.com

这就是为什么它被称为“浅”克隆:它能且仅能拷贝顶层属性。6dF28资讯网——每日最新资讯28at.com

在我们的示例中,我们使用展开运算符 ... 来执行浅克隆,但我们也可以使用 Object.assign。6dF28资讯网——每日最新资讯28at.com

const newCat = Object.assign({}, cat)

通过 JSON 深克隆

何时使用此方案:当且仅当我们需要深克隆,且我们的对象有且仅有数组、原始值和其他普通对象时。6dF28资讯网——每日最新资讯28at.com

克隆对象的一种流行方案是,将其转换为 JSON 字符串,然后解析它。6dF28资讯网——每日最新资讯28at.com

const newCat = JSON.parse(JSON.stringify(cat))newCat.name = '柴郡猫'console.log(newCat.name) //=> 柴郡猫console.log(cat.name) //=> 薛定谔newCat.girlFriends.name = '加菲猫'console.log(newCat.girlFriends.name) //=> 加菲猫console.log(cat.girlFriends.name) //=> 龙猫

虽然此方案适用于大多数情况,但它仍然有其局限性。它能且仅能转换普通对象。6dF28资讯网——每日最新资讯28at.com

// Date 对象会变成字符串JSON.parse(JSON.stringify({ now: new Date() }))// {now: '2022-07-14T13:21:36.761Z'}// undefined 对应属性人间蒸发JSON.parse(JSON.stringify({ girlFriends: undefined }))//=> {}// 无法克隆 SetJSON.parse(JSON.stringify({ set: new Set([9]) }))//=> { set: {} }// 无法克隆 SymbolJSON.parse(JSON.stringify({ symbol: Symbol('996') }))//=> {}// 无法克隆正则JSON.parse(JSON.stringify({ regex: /996/i }))//=> {}// 无法克隆 BigIntJSON.parse(JSON.stringify({ bigint: 996n }))//=> 未捕获类型错误:无法序列化 BigInt

递归克隆

何时使用此方案:当且仅当我们的对象包含复杂的结构(比如 Map/RegExp 等)时。6dF28资讯网——每日最新资讯28at.com

structuredClone 可以搞定大部分问题。6dF28资讯网——每日最新资讯28at.com

如你所愿,它通过递归遍历对象来工作。它足够机智,可以使用循环引用拷贝对象,并且知道如何克隆不同类型的数据(包括但不限于 Map/Set/Date 等)。6dF28资讯网——每日最新资讯28at.com

structuredClone({ regex: /996/i, set: new Set([9]) })//=> { regex: /996/i, set: Set(1) {9}}

它仍然有其局限性:举个栗子,它无法克隆函数或 DOM 节点。6dF28资讯网——每日最新资讯28at.com

令人鸡冻的是,它已经被所有主流浏览器支持。6dF28资讯网——每日最新资讯28at.com

粉丝请注意,它不是 ECMAScript 标准的一部分,而是浏览器 API 的一部分,并且不同浏览器的实现可能一龙一猪。Node 根本没有此 API。6dF28资讯网——每日最新资讯28at.com

或者,我们始终可以使用 lodash 的 cloneDeep,它实现了类似的算法。6dF28资讯网——每日最新资讯28at.com

完结撒花

根据情况选择特定的克隆机制。虽然我相信,在大多数情况下,JSON.parse(JSON.stringify()) 应该游刃有余,但有时我们可能想使用 structuredClone 函数来拷贝复杂的对象。在选择克隆机制之前,请了解您的数据。6dF28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-57926-0.htmlJS 中如何克隆对象?你学会了吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 告别Java -Jar启动!告诉你启动单机SpringBoot服务的正确操作方式

下一篇: JavaScript前端框架2024年展望

标签:
  • 热门焦点
  • Mate60手机壳曝光 致敬自己的经典设计

    8月3日消息,今天下午博主数码闲聊站带来了华为Mate60的第三方手机壳图,可以让我们在真机发布之前看看这款华为全新旗舰的大致轮廓。从曝光的图片看,Mate 60背后摄像头面积依然
  • 小米平板5 Pro 12.4简评:多专多能 兼顾影音娱乐的大屏利器

    疫情带来了网课,网课盘活了安卓平板,安卓平板市场虽然中途停滞了几年,但好的一点就是停滞的这几年行业又有了新的发展方向,例如超窄边框、高刷新率、多摄镜头组合等,这就让安卓
  • 一文看懂为苹果Vision Pro开发应用程序

    译者 | 布加迪审校 | 重楼苹果的Vision Pro是一款混合现实(MR)头戴设备。Vision Pro结合了虚拟现实(VR)和增强现实(AR)的沉浸感。其高分辨率显示屏、先进的传感器和强大的处理能力
  • 虚拟键盘 API 的妙用

    你是否在遇到过这样的问题:移动设备上有一个固定元素,当激活虚拟键盘时,该元素被隐藏在了键盘下方?多年来,这一直是 Web 上的默认行为,在本文中,我们将探讨这个问题、为什么会发生
  • 腾讯盖楼,字节拆墙

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之“想重温暴刷深渊、30+技能搭配暴搓到爽的游戏体验吗?一起上晶核,即刻暴打!”曾凭借直播腾讯旗下代理格斗游戏《DNF》一
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 小米汽车电池信息疑似曝光:容量101kWh,支持800V高压快充

    7月14日消息,今日一名博主在社交媒体发布了一张疑似小米汽车电池信息的照片,显示该电池包正是宁德时代麒麟电池,容量为101kWh,电压为726.7V,可以预测小
  • iQOO Neo8系列新品发布会

    旗舰双芯 更强更Pro
  • 利用职权私自解除被封帐号 Meta开除20多名员工

    11月18日消息,据外媒援引知情人士表示,过去一年时间内,Facebook母公司Meta解雇或处罚了20多名员工以及合同工,指控这些人通过内部系统以不当方式重置用户帐号,其
Top