2015-12-10 8 views
7

मुझे टाइपस्क्रिप्ट में किसी ऑब्जेक्ट को गहरा क्लोन करने की आवश्यकता है। यह कोई समस्या नहीं होनी चाहिए क्योंकि लोडाश जैसी पुस्तकालय इसके लिए उपयुक्त कार्य प्रदान करते हैं। हालांकि, ये प्रकार की जानकारी को त्यागना प्रतीत होता है।टाइपस्क्रिप्ट (प्रकार के संरक्षण) में दीप क्लोन

> var a = new SomeClass(); 
> a instanceof SomeClass; 
< true 
> var b = _.cloneDeep(a); 
> b instanceof SomeClass; 
< false 

क्या इस टाइपिंग जानकारी को संरक्षित करते समय टाइपस्क्रिप्ट में ऑब्जेक्ट क्लोन करने का कोई तरीका है?

+0

'बी: टाइपऑफ ए 'जैसे कुछ? – YOU

+4

स्वचालित रूप से? नहीं। आपको ऑब्जेक्ट और उसके नेस्टेड ऑब्जेक्ट्स पर क्लोन विधि को लागू करने की आवश्यकता होगी। –

+0

टाइपस्क्रिप्ट प्रकारों को संरक्षित करना और SomeClass.prototype को संरक्षित करना एक ही बात नहीं है। @Retsam उत्तर और https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof देखें। रनटाइम पर टाइपस्क्रिप्ट प्रकार मिटा दिए जाते हैं। –

उत्तर

4

गहरे क्लोनिंग http://blog.soulserv.net/understanding-object-cloning-in-javascript-part-ii/ के बारे में एक दिलचस्प ब्लॉग पोस्ट है।

class SomeClass { 
    constructor(public test) { 

    } 
} 

let c = new SomeClass("Hey!"); 
c.test = "Hey!"; 

console.log(c instanceof SomeClass); // returns true 

let cloneC = clone(c, /* resolve circular references */ true); 

console.log(cloneC instanceof SomeClass); // returns true 

[clone() source code] [Complete source code]

6

टाइपप्रति यहाँ प्रकार की जानकारी को त्यागकर नहीं है: आप गहरी क्लोनिंग clone() समारोह के लेखक का कार्यान्वयन का उपयोग कर सकते हैं। DefinitelyTyped lodash.d.ts फ़ाइल में, आप देख सकते हैं कि cloneDeep तर्क हम परवाह नहीं है की उपेक्षा के रूप में

cloneDeep<T>(
    val: T, 
    customizer?: (value: any) => any, 
    thisArg?: any 
) : T 

परिभाषित किया गया है, यह इनपुट के रूप में एक T लेता है, और एक T उत्पादन के रूप में बाहर थूक। तो टाइपस्क्रिप्ट किसी भी प्रकार की जानकारी खो नहीं रहा है; यह cloneDeep के आउटपुट को इनपुट के समान प्रकार के रूप में मानता है।

आपको इसे अपने संपादक के माध्यम से सत्यापित करने में सक्षम होना चाहिए: मान लें कि आपके पास कुछ संपादक है जो आपको चर के प्रकार या स्वत: पूर्ण विधियों का निरीक्षण करने देता है (जो मैं अत्यधिक अनुशंसा करता हूं, यदि आप नहीं करते हैं)।


फिर typeof क्यों काम नहीं कर रहा है? ऐसा इसलिए है क्योंकि टाइपस्क्रिप्ट प्रकार की जानकारी रनटाइम पर नहीं ले जाती है।

"use strict"; 
 
class A {} 
 

 
let a = new A(); 
 
let b = _.cloneDeep(a); 
 

 
if (b instanceof A) { 
 
    alert("b is an instance of A"); 
 
} else { 
 
    alert("b is not an instance of A"); 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>

कारण यह है कि b instanceof A गलत है कि instanceof जाँच कर रहा है है: instanceof एक देशी जे एस ऑपरेटर, जो टाइपप्रति इस स्निपेट चलाकर, की जो आप देख सकते हैं व्यवहार में परिवर्तन नहीं होता है रचनाकारों के खिलाफ: x instanceof A सत्य लौटाता है यदि फ़ंक्शन A एक्स की प्रोटोटाइप श्रृंखला में कहीं भी एक कन्स्ट्रक्टर है (instanceof पर एमडीएन दस्तावेज देखें)। हालांकि, लोडाश रचनाकारों का उपयोग नहीं करता है जब यह वस्तुओं को क्लोन करता है। यह नहीं कर सकता (यह कैसे पता चलेगा कि कौन से तर्क पारित किए जाएंगे?) यह एक सादा जेएस ऑब्जेक्ट बनाता है जिसमें क्लोन ऑब्जेक्ट के सभी तरीके हैं, लेकिन इसकी प्रोटोटाइप श्रृंखला पुन: उत्पन्न नहीं होती है।

लोडाश के clone (और लॉनाश के अधिकांश तरीकों, वास्तव में) कच्चे जेएस ऑब्जेक्ट्स से निपटने के दौरान सबसे अच्छा उपयोग किया जाता है। यदि आप इसे रचनाकारों के साथ संयोजन में उपयोग कर रहे हैं और instanceof चीजों की जांच करना थोड़ा अस्पष्ट हो जाता है। यहाँ


एक समाधान instanceof चेकिंग से बचने के लिए, और बतख टाइपिंग के लिए कुछ सदृश करने के लिए है, यह जांच न करें कि ऑब्जेक्ट का कन्स्ट्रक्टर एक विशेष कार्य है, लेकिन जांच करें कि ऑब्जेक्ट में वे गुण हैं जिनकी आप अपेक्षा करते हैं।

एक अन्य समाधान, के रूप में टिप्पणी में सुझाव दिया, अपने वर्ग पर ही एक क्लोन विधि है, जो lodash का उपयोग नहीं होता लागू कर रहा है।

class A() { 
    clone() { 
     var cloned = new A(); //pass appropriate constructor args 
     //make other necessary changes to make the state match 
     return cloned; 
    } 
} 
1

आप Lodash#cloneDeep उपयोगिता का उपयोग कर सकते हैं। उपयोग का उदाहरण:

import * as _ from "lodash"; 

... 

{ 
    this.cloned = _.cloneDeep(data); 
} 
संबंधित मुद्दे