संरचित क्लोनिंग
HTML मानक में एक आंतरिक संरचित क्लोनिंग / क्रमांकन एल्गोरिथ्म शामिल है जो वस्तुओं के गहरे क्लोन बना सकता है। यह अभी भी कुछ अंतर्निहित प्रकारों तक सीमित है, लेकिन JSON द्वारा समर्थित कुछ प्रकारों के अलावा यह Dates, RegExps, Maps, Sets, Blobs, FileLists, ImageDatas, Sparse Arrays, Typr Arrays और शायद भविष्य में और अधिक का समर्थन करता है। । यह क्लोन डेटा के भीतर संदर्भों को भी संरक्षित करता है, जिससे यह चक्रीय और पुनरावर्ती संरचनाओं का समर्थन करने की अनुमति देता है जो JSON के लिए त्रुटियां पैदा करेगा।
Node.js में समर्थन: प्रायोगिक j
v8
Node.js वर्तमान में मॉड्यूल (नोड 11) के रूप में सीधे संरचित क्रमबद्धता एपीआई को उजागर करता है , लेकिन इस कार्यक्षमता अभी भी "प्रायोगिक", और भविष्य के संस्करणों में परिवर्तन या हटाने के अधीन के रूप में चिह्नित किया गया है। यदि आप एक संगत संस्करण का उपयोग कर रहे हैं, तो किसी ऑब्जेक्ट को क्लोन करना उतना ही सरल है:
const v8 = require('v8');
const structuredClone = obj => {
return v8.deserialize(v8.serialize(obj));
};
ब्राउज़रों में प्रत्यक्ष समर्थन: शायद आखिरकार? 😐
ब्राउज़र्स वर्तमान में संरचित क्लोनिंग एल्गोरिथ्म के लिए एक सीधा इंटरफ़ेस प्रदान नहीं करते हैं, लेकिन एक वैश्विक structuredClone()
फ़ंक्शन पर चर्चा की गई है GitHub पर whatwg / html # 793 । जैसा कि वर्तमान में प्रस्तावित है, अधिकांश प्रयोजनों के लिए इसका उपयोग करना उतना ही सरल होगा:
const clone = structuredClone(original);
जब तक इसे शिप नहीं किया जाता है, तब तक ब्राउज़र की संरचित क्लोन कार्यान्वयन केवल अप्रत्यक्ष रूप से उजागर होते हैं।
अतुल्यकालिक वर्कअराउंड: उपयोग करने योग्य। 😕
मौजूदा एपीआई के साथ एक संरचित क्लोन बनाने के लिए निचला-ओवरहेड तरीका एक संदेशचैन के एक पोर्ट के माध्यम से डेटा को पोस्ट करना है । अन्य पोर्ट message
संलग्न की एक संरचित क्लोन के साथ एक घटना का उत्सर्जन करेगा .data
। दुर्भाग्य से, इन घटनाओं के लिए सुनना अनिवार्य रूप से अतुल्यकालिक है, और तुल्यकालिक विकल्प कम व्यावहारिक हैं।
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();
तुल्यकालिक Workarounds: भयानक! 🤢
तुल्यकालिक रूप से संरचित क्लोन बनाने के लिए कोई अच्छा विकल्प नहीं हैं। यहाँ कुछ अव्यवहारिक हैक्स के बजाय हैं।
history.pushState()
और history.replaceState()
दोनों अपने पहले तर्क का एक संरचित क्लोन बनाते हैं, और उस मान को असाइन करते हैं history.state
। आप इसका उपयोग किसी वस्तु का संरचित क्लोन बनाने के लिए इस तरह कर सकते हैं:
const structuredClone = obj => {
const oldState = history.state;
history.replaceState(obj, null);
const clonedObj = history.state;
history.replaceState(oldState, null);
return clonedObj;
};
उदाहरण का उपयोग करें:
'use strict';
const main = () => {
const original = { date: new Date(), number: Math.random() };
original.self = original;
const clone = structuredClone(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.");
};
const structuredClone = obj => {
const oldState = history.state;
history.replaceState(obj, null);
const clonedObj = history.state;
history.replaceState(oldState, null);
return clonedObj;
};
main();
हालांकि तुल्यकालिक, यह बेहद धीमा हो सकता है। यह ब्राउज़र इतिहास में हेरफेर करने से जुड़े सभी ओवरहेड को उकसाता है। इस विधि को बार-बार कॉल करने पर Chrome अस्थायी रूप से अनुत्तरदायी बन सकता है।
Notification
निर्माता अपने संबद्ध डेटा का संरचित क्लोन पैदा करता है। यह उपयोगकर्ता को एक ब्राउज़र सूचना प्रदर्शित करने का भी प्रयास करता है, लेकिन यह तब तक चुपचाप विफल रहेगा जब तक आपने अधिसूचना अनुमति का अनुरोध नहीं किया है। यदि आपके पास अन्य प्रयोजनों के लिए अनुमति है, तो हम तुरंत हमारे द्वारा बनाई गई अधिसूचना को बंद कर देंगे।
const structuredClone = obj => {
const n = new Notification('', {data: obj, silent: true});
n.onshow = n.close.bind(n);
return n.data;
};
उदाहरण का उपयोग करें:
'use strict';
const main = () => {
const original = { date: new Date(), number: Math.random() };
original.self = original;
const clone = structuredClone(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.");
};
const structuredClone = obj => {
const n = new Notification('', {data: obj, silent: true});
n.close();
return n.data;
};
main();