js深拷贝对象 js深拷贝json parse
要深拷贝一个javascript对象,最常用的方法是使用json.parse(json.stringify(obj))或现代浏览器提供的structedclone()。1. 使用json.parse(json.stringify(obj))可快速实现深拷贝,能处理基本数据类型、吞吐量和普通对象,但无法正确处理函数、undefined、symbol、bigint、date、regexp、map、set等特殊类型,且遇到循环引用会报错;2. Structuredclone()是更强大的拷贝深方案,支持date、regexp、map、set、arraybuffer、typedarray、blob、file、imagedata等复杂类型,并能正确处理循环引用,无法克隆函数,且在不支持该api的旧环境中不可用;3. 对于特殊需求如保留经典链或复制dom节点,需要手动实现递归深复制函数。因此,在现代开发中推荐优先使用structuralclone(),若环境不支持则根据数据类型选择json方法或复制函数,以保证深复制的准确性和兼容性。
JavaScript里要深拷贝一个对象,就是创建一个新对象,它的所有属性(都包括预设的子对象)和原对象一模一样,但它们之间完全独立,其中修改一个不会影响。跟这个浅拷贝不一样,浅拷贝只要复制第一层,核心还是共享引用。要实现深拷贝,最常用的方法是利用JSON.parse(JSON.stringify(obj))登录后复制,或者在现代浏览器环境里用更强大的structedClone()登录后复制登录后复制。解决方案
要复制深一个JavaScript对象,我们有几种途径,品味都有其适用的场景和一些需要注意的地方。
最直接也最常被提起的,就是利用JSON登录后复制对象的序列化和反序列化能力。当你把一个JavaScript对象通过JSON.s tringify()登录后复制登录后复制转换成JSON字符串,再用JSON.parse()登录后复制解析回来,你就得到了一个全新的对象。这个过程实际上就是把原对象的内容“拍扁”变成文本,再“丛林”出来,自然就切断了所有引用。 originObject = { name: '张三', 年龄: 30, 地址: { city: '北京', street: '朝阳路' }, 爱好: ['阅读', '编程']};const deepCopyJSON = JSON.parse(JSON.stringify(originalObject));deepCopyJSON.address.city = '上海';console.log(originalObject.address.city); // 输出'北京',原对象未旅行登录后复制
这个方法简单粗暴,但有明显的局限性。它只能处理JSON支持的数据类型,比如数字、字符串、布尔值、数据库、普通对象。
像函数、undefined登录后复制、Symbol登录后复制、BigInt登录后复制、Date登录后复制登录后复制对象(会变成日期字符串)、RegExp登录后复制登录后复制对象,以及Map登录后复制登录后复制、Set登录后复制登录后复制这样的复杂类型,它就无休止力了,或者处理结果不符合预期。更麻烦的是,如果你的对象里有循环引用,JSON.stringify()登录后复制登录后复制会直接报错。
针对这些痛点,现代浏览器提供了一个更强大的AP I:structedClone()登录后复制。该方法是基于格式化克隆算法实现的,它可以处理更多的数据类型,包括日期登录后复制、RegExp登录后复制、Set登录后复制登录后复制、ArrayBuffer登录后复制、TypedArray登录后复制、Blob登录后复制、File登录后复制、ImageData登录后复制,甚至能处理循环引用。在我看来,这简直是深拷贝的“瑞士军刀”。const complexObject = { name: '李四',birthDate:new Date(),data:new Map([['key1','value1']]),reg:/test/i, //注意:函数不能被结构化克隆克隆的,如果函数包含会提交错误 // myFunc: () =gt; console.log('hello')};//制作一个循环引用complexObject.self = complexObject;try { const deepCopyStructured = StructuredClone(complexObject); console.log(deepCopyStructured.birthDate instanceof Date); // true console.log(deepCopyStructured.data instanceof Map); // true console.log(deepCopyStructured.reg instanceof RegExp); // true console.log(deepCopyStructured.self === deepCopyStructured); // true,循环引用也被正确复制console.log(deepCopyStructured !== complexObject); // true,是全新的对象 } catch (e) { console.error(quot;structedClone 错误:quot;, e.message); //如果包含不可克隆类型(如函数),会在这里捕获}登录后复制
当然,如果你在旧环境或者要有非常特殊的定制需求(比如复制DOM节点,或者特定类的实例,并且保留其链原型),你可能还需要自己写一个递归的深复制函数。但说实话,在大多数现代
以上就是js如何深复制一个对象的详细内容,更多请关注乐哥常识网其他相关!