दिलचस्प पोस्ट
"Java-server" और "java -client" के बीच वास्तविक मतभेद? Android में JSON को कैसे पार्स करना है अपने घटक GUID को wix में बदलें? क्यों तारीख। गलत गलत परिणाम देते हैं? हायफन (-) चरित्र से शुरू होने वाली फाइल नाम के साथ मैं कैसे काम कर सकता हूं? IOS में numpad कीबोर्ड में 'संपन्न' बटन जोड़ने के लिए कैसे करें CGContextDrawImage UIImage.CGImage पास करते समय छवि को ऊपर की ओर खींचती है पृष्ठ के निचले भाग में फुटर फ़्लशिंग, ट्विटर बूटस्ट्रैप आप LINQ से SQL के साथ एक उप-क्वेरी कैसे प्रबंधित कर सकते हैं? "पोस्ट / रीडायरेक्ट / गेट" को समझना MySQL में पैसे के मूल्यों को स्टोर करने के लिए सर्वश्रेष्ठ डेटा प्रकार एकाधिक कैप्चर-समूहों के साथ आरगेक्स समूह आर आर जावा के लैम्ब्डा वाक्यविन्यास के लिए क्या टूटना है? सहेजे गए NSUserDefaults देखने का आसान तरीका? PostgreSQL में कई-से-कई रिश्तों को कैसे कार्यान्वित करें?

जावास्क्रिप्ट में दीप क्लोन कैसे करें

आप जावास्क्रिप्ट ऑब्जेक्ट को कैसे क्लोन करते हैं?

मुझे पता है कि चौखटे JSON.parse(JSON.stringify(o)) और $.extend(true, {}, o) आधार पर विभिन्न कार्य हैं लेकिन मैं इस तरह एक ढांचे का उपयोग नहीं करना चाहता हूं

गहरी क्लोन बनाने का सबसे शानदार या कुशल तरीका क्या है

हम क्लोनिंग एरे की तरह बढ़त वाले मामलों की देखभाल करते हैं आत्म संदर्भ से निपटने, प्रोटोटाइप श्रृंखला नहीं तोड़ना।

हमें डीओएम ऑब्जेक्ट्स की प्रतिलिपि के बारे में परवाह नहीं है और जैसे कि .cloneNode इस कारण से मौजूद है।

जैसा कि मैं मुख्य रूप से v8 इंजन की node.js सुविधाओं का उपयोग कर node.js में गहरी क्लोन का उपयोग करना चाहता हूं, स्वीकार्य है।

[संपादित करें]

कोई भी सुझाव देने से पहले मुझे यह बताएं कि प्रतिलिपि वस्तु से विरासत में मिली और इसे क्लोनिंग करके प्रतिलिपि बनाने में एक अलग अंतर है। पूर्व प्रोटोटाइप श्रृंखला की गड़बड़ करता है।

[आगे संपादित करें]

अपना जवाब पढ़ने के बाद, मैं कष्टप्रद खोज में आया हूं कि संपूर्ण वस्तुओं की क्लोनिंग एक बहुत खतरनाक और कठिन खेल है। उदाहरण के लिए निम्नलिखित समापन आधारित ऑब्जेक्ट लें

 var o = (function() { var magic = 42; var magicContainer = function() { this.get = function() { return magic; }; this.set = function(i) { magic = i; }; } return new magicContainer; }()); var n = clone(o); // how to implement clone to support closures 

क्या एक क्लोन फ़ंक्शन लिखने का कोई तरीका है जो ऑब्जेक्ट को क्लोन करता है, क्लोनिंग के समय समान स्थिति होती है, लेकिन जेएस में जेएस पार्सर को लिखे बिना o राज्य को बदल नहीं सकता।

इस तरह के किसी फ़ंक्शन के लिए कोई वास्तविक दुनिया की आवश्यकता नहीं होनी चाहिए। यह केवल अकादमिक रुचि है

वेब के समाधान से एकत्रित समाधान "जावास्क्रिप्ट में दीप क्लोन कैसे करें"

यह सचमुच निर्भर करता है कि आप क्या क्लोन करना चाहते हैं। क्या यह वास्तव में जेएसएएन ऑब्जेक्ट या जावास्क्रिप्ट में कोई वस्तु है? यदि आप किसी क्लोन करना चाहते हैं, तो यह आपको कुछ परेशानी में ले सकता है। कौन सी परेशानी? मैं इसे नीचे समझाता हूं, लेकिन सबसे पहले, एक कोड उदाहरण जो क्लोन ऑब्जेक्ट लिटरल्स, कोई प्राइमेटिव, एरे और नोड्स

 function clone(item) { if (!item) { return item; } // null, undefined values check var types = [ Number, String, Boolean ], result; // normalizing primitives if someone did new String('aaa'), or new Number('444'); types.forEach(function(type) { if (item instanceof type) { result = type( item ); } }); if (typeof result == "undefined") { if (Object.prototype.toString.call( item ) === "[object Array]") { result = []; item.forEach(function(child, index, array) { result[index] = clone( child ); }); } else if (typeof item == "object") { // testing that this is DOM if (item.nodeType && typeof item.cloneNode == "function") { var result = item.cloneNode( true ); } else if (!item.prototype) { // check that this is a literal if (item instanceof Date) { result = new Date(item); } else { // it is an object literal result = {}; for (var i in item) { result[i] = clone( item[i] ); } } } else { // depending what you would like here, // just keep the reference, or create new object if (false && item.constructor) { // would not advice to do that, reason? Read below result = new item.constructor(); } else { result = item; } } } else { result = item; } } return result; } var copy = clone({ one : { 'one-one' : new String("hello"), 'one-two' : [ "one", "two", true, "four" ] }, two : document.createElement("div"), three : [ { name : "three-one", number : new Number("100"), obj : new function() { this.name = "Object test"; } } ] }) 

और अब, हम उन समस्याओं के बारे में बात करते हैं जो आपको वास्तविक वस्तुओं की क्लोनिंग शुरू करने पर प्राप्त हो सकती हैं। मैं अब बात कर रहा हूँ, वस्तुओं के बारे में जो कुछ भी करके आप बनाते हैं

 var User = function(){} var newuser = new User(); 

बेशक आप उन्हें क्लोन कर सकते हैं, यह एक समस्या नहीं है, हर ऑब्जेक्ट कन्स्ट्रक्टर संपत्ति का पर्दाफाश करता है, और आप वस्तुओं को क्लोन करने के लिए इसका उपयोग कर सकते हैं, लेकिन यह हमेशा काम नहीं करेगा। आप इस ऑब्जेक्ट for in भी सरल कर सकते हैं, लेकिन यह एक ही दिशा में जाता है – परेशानी मैंने कोड के अंदर क्लोन की कार्यक्षमता भी शामिल की है, लेकिन if( false ) कथन से बाहर रखा गया है

तो, क्लोनिंग क्यों दर्द हो सकता है? ठीक है, सबसे पहले, हर वस्तु / उदाहरण में कुछ राज्य हो सकते हैं आप कभी भी यह सुनिश्चित नहीं कर सकते हैं कि आपके ऑब्जेक्ट के लिए निजी वैरिएबल नहीं है, और यदि ऐसा है, तो वस्तु क्लोनिंग करके, आप राज्य को तोड़ सकते हैं

कल्पना करो कि कोई राज्य नहीं है, यह ठीक है। तो फिर भी हमारे पास एक और समस्या है। "कन्स्ट्रक्टर" विधि के माध्यम से क्लोन करना हमें एक और बाधा देगा। यह एक बहस निर्भरता है आप कभी भी यह सुनिश्चित नहीं कर सकते हैं कि जिसने इस वस्तु को बनाया है, उसने कुछ नहीं किया

 new User({ bike : someBikeInstance }); 

यदि यह मामला है, तो आप भाग्य से बाहर हैं, कुछ बाईबल इन्स्टेंस शायद कुछ संदर्भ में बनाया गया था और यह संदर्भ क्लोन पद्धति के लिए अज्ञात है।

इसलिए क्या करना है? आप अभी भी समाधान के for in कर सकते हैं, और सामान्य ऑब्जेक्ट लिटरल्स जैसे वस्तुओं का इलाज कर सकते हैं, लेकिन शायद यह एक ऐसा विचार है कि ऐसी वस्तुओं को क्लोन करना बिल्कुल नहीं है, और इस ऑब्जेक्ट के संदर्भ को केवल पास करें?

एक अन्य समाधान है – आप एक सम्मेलन निर्धारित कर सकते हैं कि सभी वस्तुओं को क्लोन किया जाना चाहिए, इस भाग को स्वयं स्वयं लागू करना चाहिए और उपयुक्त API पद्धति (जैसे क्लोन ऑब्जेक्ट) प्रदान करना चाहिए। कुछ जो cloneNode DOM के लिए कर रहा है

आप तय करें।

बहुत आसान तरीका है, शायद बहुत आसान है:

 var cloned = JSON.parse(JSON.stringify(objectToClone)); 

JSON.parse(JSON.stringify()) . JSON.parse(JSON.stringify()) गहरी प्रतिलिपि में संयोजन Javascript ऑब्जेक्ट अप्रभावी हैक है, क्योंकि JSON undefined और function () {} मूल्यों का समर्थन नहीं करता है, और इसलिए JSON.stringify कोड के उन वर्गों को अनदेखा कर देगा, जब "स्ट्रिंगिंग" (मार्शलिंग) जावास्क्रिप्ट ऑब्जेक्ट JSON में है

निम्न कार्य ऑब्जेक्ट की गहरी प्रतिलिपि करेगा, और किसी तृतीय पक्ष लाइब्रेरी (jQuery, लोडाश, आदि) की आवश्यकता नहीं है।

 function copy(aObject) { var bObject, v, k; bObject = Array.isArray(aObject) ? [] : {}; for (k in aObject) { v = aObject[k]; bObject[k] = (typeof v === "object") ? copy(v) : v; } return bObject; } 

Underscore.js contrib पुस्तकालय पुस्तकालय एक समारोह स्पीपशॉट कहा जाता है कि एक वस्तु गहरे क्लोन है

स्रोत से स्निपेट:

 snapshot: function(obj) { if(obj == null || typeof(obj) != 'object') { return obj; } var temp = new obj.constructor(); for(var key in obj) { if (obj.hasOwnProperty(key)) { temp[key] = _.snapshot(obj[key]); } } return temp; } 

एक बार लाइब्रेरी आपकी प्रोजेक्ट से जुड़ा हुआ है, फ़ंक्शन का उपयोग करके बस का उपयोग करें

 _.snapshot(object); 

यहां एक ES6 फ़ंक्शन है जो चक्रीय संदर्भ वाले ऑब्जेक्ट के लिए भी काम करेगा:

 function deepClone(obj, hash = new WeakMap()) { if (Object(obj) !== obj) return obj; // primitives if (hash.has(obj)) return hash.get(obj); // cyclic reference const result = obj instanceof Date ? new Date(obj) : obj instanceof RegExp ? new RegExp(obj.source, obj.flags) : obj.constructor ? new obj.constructor() : Object.create(null); hash.set(obj, result); if (obj instanceof Map) Array.from(obj, ([key, val]) => result.set(key, deepClone(val, hash)) ); return Object.assign(result, ...Object.keys(obj).map ( key => ({ [key]: deepClone(obj[key], hash) }) )); } // Sample data var p = { data: 1, children: [{ data: 2, parent: null }] }; p.children[0].parent = p; var q = deepClone(p); console.log(q.children[0].parent.data); // 1 

जैसा कि अन्य लोगों ने इस तरह के और इसी तरह के प्रश्नों पर ध्यान दिया है, सामान्य अर्थों में "ऑब्जेक्ट" क्लोनिंग, जावास्क्रिप्ट में संदेहास्पद है।

हालांकि, वस्तुओं का एक वर्ग है, जिसे मैं "डेटा" ऑब्जेक्ट्स को कैल कर दूंगा, जो कि { ... } लिटलल्स और / या साधारण प्रॉपर्टी असाइनमेंट से बना है या JSON से डिसेराइज़ किए गए हैं, जिसके लिए यह क्लोन करना उचित है। बस आज मैं एक बड़े डेटा सेट के लिए क्या होता है यह परीक्षण करने के लिए 5 x से सर्वर से प्राप्त आंकड़ों को कृत्रिम रूप से फुलाया जाना चाहता था, लेकिन ऑब्जेक्ट (एक सरणी) और उसके बच्चों को सही ढंग से काम करने के लिए वस्तुएं अलग-अलग ऑब्जेक्ट की जानी थीं क्लोनिंग ने मुझे अपने डेटा सेट को गुणा करने के लिए ऐसा करने की अनुमति दी:

 return dta.concat(clone(dta),clone(dta),clone(dta),clone(dta)); 

दूसरी जगह मैं क्लोनिंग डेटा ऑब्जेक्ट्स को समाप्त कर देता हूं, डेटा को होस्ट को वापस भेजने के लिए, जहां मैं इसे भेजने से पहले डेटा मॉडल में ऑब्जेक्ट से राज्य फ़ील्ड पट्टी करना चाहता हूं। उदाहरण के लिए, मैं ऑब्जेक्ट से "_" से प्रारंभ होने वाले सभी फ़ील्ड को क्लोन करना चाहता हूं।

यह कोड है जिसे मैंने सामान्य रूप से यह करने के लिए लिखना समाप्त किया, जिसमें सहायक सरणियों और चयनकर्ता को चुनने के लिए सदस्यों को क्लोन करना (जो संदर्भ निर्धारित करने के लिए "पथ" स्ट्रिंग का उपयोग करता है) शामिल हैं:

 function clone(obj,sel) { return (obj ? _clone("",obj,sel) : obj); } function _clone(pth,src,sel) { var ret=(src instanceof Array ? [] : {}); for(var key in src) { if(!src.hasOwnProperty(key)) { continue; } var val=src[key], sub; if(sel) { sub+=pth+"/"+key; if(!sel(sub,key,val)) { continue; } } if(val && typeof(val)=='object') { if (val instanceof Boolean) { val=Boolean(val); } else if(val instanceof Number ) { val=Number (val); } else if(val instanceof String ) { val=String (val); } else { val=_clone(sub,val,sel); } } ret[key]=val; } return ret; } 

सरल उचित गहरे क्लोन समाधान, एक गैर-नल रूट ऑब्जेक्ट मानते हुए और कोई सदस्य चयन नहीं है:

 function clone(src) { var ret=(src instanceof Array ? [] : {}); for(var key in src) { if(!src.hasOwnProperty(key)) { continue; } var val=src[key]; if(val && typeof(val)=='object') { val=_clone(val); } ret[key]=val; } return ret; } 

मैंने देखा कि नक्शा को विशेष उपचार की आवश्यकता होती है, इस प्रकार इस सूत्र में सभी सुझावों के साथ कोड होगा:

 function deepClone( obj ) { if( !obj || true == obj ) //this also handles boolean as true and false return obj; var objType = typeof( obj ); if( "number" == objType || "string" == objType ) // add your immutables here return obj; var result = Array.isArray( obj ) ? [] : !obj.constructor ? {} : new obj.constructor(); if( obj instanceof Map ) for( var key of obj.keys() ) result.set( key, deepClone( obj.get( key ) ) ); for( var key in obj ) if( obj.hasOwnProperty( key ) ) result[key] = deepClone( obj[ key ] ); return result; } 

यह गहरी क्लोनिंग विधि है जो मैं करता हूं, मुझे लगता है कि यह महान है, आशा है कि आप सुझाव देंगे

 function deepClone (obj) { var _out = new obj.constructor; var getType = function (n) { return Object.prototype.toString.call(n).slice(8, -1); } for (var _key in obj) { if (obj.hasOwnProperty(_key)) { _out[_key] = getType(obj[_key]) === 'Object' || getType(obj[_key]) === 'Array' ? deepClone(obj[_key]) : obj[_key]; } } return _out; }