structuredClone
structuredClone
是 HTML5
中新增的一个 API
,它可以用来实现 Web Worker
之间的通信。
文档
structuredClone 的使用
const obj = {
a: 1,
b: {
c: 1,
},
};
const res = structuredClone(obj);
console.log(res); // {a: 1, b: {c: 1}}
obj.a = 2;
console.log(obj); // {a: 2, b: {c: 1}}
console.log(res); // {a: 1, b: {c: 1}}
obj.b.c = 2;
console.log(obj); // {a: 2, b: {c: 2}}
console.log(res); // {a: 1, b: {c: 1}}
另外一种实现
import structuredClone from '@ungap/structured-clone';
看到了一个用 MessageChannel
实现的深拷贝,简直就是秀儿啊
class StructuredCloner {
constructor() {
this.pendingClones_ = new Map();
this.nextKey_ = 0;
const channel = new MessageChannel();
this.inPort_ = channel.port1;
this.outPort_ = channel.port2;
this.outPort_.onmessage = ({ data: { key, value } }) => {
const resolve = this.pendingClones_.get(key);
resolve(value);
this.pendingClones_.delete(key);
};
this.outPort_.start();
}
cloneAsync(value) {
return new Promise((resolve) => {
const key = this.nextKey_++;
this.pendingClones_.set(key, resolve);
this.inPort_.postMessage({ key, value });
});
}
}
const structuredCloneAsync = (window.structuredCloneAsync =
StructuredCloner.prototype.cloneAsync.bind(new StructuredCloner()));
测试
const main = async () => {
const original = { date: new Date(), number: Math.random() };
original.self = original;
const clone = await structuredCloneAsync(original);
// They're different objects:
console.assert(original !== clone);
console.assert(original.date !== clone.date);
// They're cyclical:
console.assert(original.self === original);
console.assert(clone.self === clone);
// They contain equivalent values:
console.assert(original.number === clone.number);
console.assert(Number(original.date) === Number(clone.date));
console.log("Assertions complete.");
};
main();