JavaScript中的拷贝(复制)有两种:浅拷贝和深拷贝。
浅拷贝只复制基本数据类型的值,而对于引用数据类型(如对象,数组等),只复制了其引用地址,因此它们指向同一个对象,当一个对象的值改变,另一个对象的值也会跟着改变。
而深拷贝则会复制出一个全新的对象,与被复制的对象互不影响。
这里介绍一种深拷贝方法,即使用“structuredClone”。
1. structuredClone概念
structuredClone是HTML5中的API,它可以对现有对象进行深拷贝,生成一个新的、与原对象内容完全相等的对象。structuredClone支持绝大多数JS对象,包括Array,Date,RegExp,Blob,FileList等等,但不支持Function,Error和DOM节点等引用类型。
2. structuredClone使用说明
2.1 示例1
function deepClone(obj) {
return new Promise((resolve, reject) => {
const { port1, port2 } = new MessageChannel();
port1.onmessage = ev => resolve(ev.data);
port2.postMessage(obj);
});
}
let obj = {
a: 1,
b: {
c: 2,
d: {
e: 3,
f: [4,5,6]
}
}
};
deepClone(obj).then(res => {
console.log(res); // 深拷贝后的新对象
});
上述代码中,我们定义了一个deepClone方法,接收一个对象obj作为参数。在deepClone方法中,我们创建了一个新的MessageChannel,该消息通道有两个端口,用于通信。在拷贝对象时,我们向port2发送了obj对象,接着在port1端口里监听onmessage事件,在事件回调中用resolve方法返回拷贝后的新对象。
2.2 示例2
function deepClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
let obj = {
a: 1,
b: {
c: 2,
d: {
e: 3,
f: [4,5,6]
}
}
};
let newObj = deepClone(obj);
console.log(newObj); // 深拷贝后的新对象
上述代码中,我们定义了一个deepClone方法,利用 JSON.parse(JSON.stringify(obj))这段代码实现对象的深拷贝。
首先,JSON.stringify()能将一个JavaScript对象转化为JSON字符串,而JSON字符串是不包含任何JavaScript对象的方法或数据的,也就是说,JSON.stringify方法过滤掉了参数对象中的不可枚举属性,包括对象原型中的不可枚举属性,同时不能正确处理Date、RegExp、Error等引用类型数据,和 undefined,NaN,Infinity等特殊值。因此,此方法并不是一种万能的深拷贝方法。
随后,利用JSON.parse()方法能够将JSON字符串转化为JavaScript对象,这时我们便可得到一个新的深拷贝后的对象。但这种方法的问题是,它不能保留对象原型上的数据和函数,并且当对象中存在循环引用的情况时,会抛出异常。
3. 总结
从上述内容中可以看出,使用structuredClone()或JSON.parse(JSON.stringify(obj))方法实现对象的深拷贝各有优劣,因此在实际使用过程中,我们需要根据对象的特点来选择适合的方法。同时,在开发中,为了保证代码的健壮性和效率,我们应该针对不同类型对象的情况,使用不同的深拷贝方案。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript深拷贝方法structuredClone使用 - Python技术站