2015-03-20 4 views
5

एक रेपो में मैंने एक रेखा देखी।जावास्क्रिप्ट ऑब्जेक्ट से स्ट्रिप विधियां

var foo = JSON.parse(JSON.stringify(foo)); 

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

उत्तर

6

code context में आपने अब खुलासा किया है, इस तकनीक का उपयोग किसी कार्य को पारित ऑब्जेक्ट की एक प्रति बनाने के लिए किया जा रहा है ताकि उस ऑब्जेक्ट में संशोधनों को मूल संशोधित नहीं किया जा सके।

// route reply/error 
this.connection.on('message', function(msg) { 
    var msg = JSON.parse(JSON.stringify(msg)); 
    var handler; 
    if (msg.type == constants.messageType.methodReturn || msg.type == constants.messageType.error) { 
     handler = self.cookies[msg.replySerial]; 
     if (msg.type == constants.messageType.methodReturn && msg.body) 
      msg.body.unshift(null); // first argument - no errors, null 
     if (handler) { 
      delete self.cookies[msg.replySerial]; 
      var props = { 
      connection: self.connection, 
      bus: self, 
      message: msg, 
      signature: msg.signature 
      }; 
      if (msg.type == constants.messageType.methodReturn) 
      handler.apply(props, msg.body); // body as array of arguments 
      else 
      handler.call(props, msg.body); // body as first argument 
     } 

नोट:: इस क्लिप कि msg.body.unshift(null) शामिल में लाइन यहाँ अपने लिंक से संदर्भ है। अगर यह प्रतिलिपि नहीं बनाई गई तो वह मूल वस्तु को संशोधित करेगा।

इसके अलावा, ध्यान दें कि var msg को फिर से शुरू करना वास्तव में एक नया चर परिभाषित नहीं कर रहा है। चूंकि msg पहले से ही इस दायरे में फ़ंक्शन तर्क के रूप में परिभाषित किया गया है, इसलिए इसे var msg द्वारा पुन: घोषित नहीं किया गया है (यह तकनीकी रूप से var का उपयोग करने के लिए कोड में एक गलती है)।


कोड के इस प्रकार का उपयोग कर के लिए सामान्य कारण एक वस्तु (वस्तु जहां एम्बेडेड ऑब्जेक्ट और सारणियों सहित सभी गुण कॉपी कर रहे हैं की एक गहरी प्रतिलिपि बनाने) क्लोन करने के लिए है।

var obj = { 
    list: [1,2,3], 
    items: [{language: "English", greeting: "hello"}, 
      {language: "Spanish", greeting: "hola"}, 
      {language: "French", greeting: "bonjour"}] 
} 

// make a completely independent copy of obj 
var copy = JSON.parse(JSON.stringify(obj)); 

copy.items[0].greeting = "Yo"; 

console.log(obj.items[0].greeting); // "hello" 
console.log(copy.items[0].greeting); // "Yo" 

नोट: वस्तुओं है कि एक सादे ऑब्जेक्ट प्रकार कर रहे हैं और कि कार्य हैं कस्टम गुण नहीं है के साथ एक पूरी कॉपी के रूप में यह केवल काम करता है। और, क्योंकि JSON.stringify() परिपत्र संदर्भ या स्वयं संदर्भों का समर्थन नहीं करता है, तो उनमें से कोई भी नहीं हो सकता है। और, यदि आपके पास एक ही ऑब्जेक्ट के कई संदर्भ हैं, तो प्रत्येक संदर्भ को एक नई अलग ऑब्जेक्ट में कॉपी किया जाएगा। और, JSON.stringify() और JSON.parse() का संयोजन सादा Object जैसे RegExp, Date या अपनी किसी भी कस्टम ऑब्जेक्ट्स (वे उन्हें सादे ऑब्जेक्ट्स में बदल देते हैं) के अलावा अन्य ऑब्जेक्ट्स का समर्थन नहीं करते हैं। इसलिए, इस प्रक्रिया की कुछ सीमाएं हैं, लेकिन यह ज्यादातर मामलों के लिए काफी सरलता से काम करती है।


प्रति मैट

(टिप्पणी में), एक कस्टम समारोह एक वस्तु है कि वृत्तीय संदर्भ का समर्थन और कस्टम वस्तुओं के कुछ प्रकार के here देखा जा सकता है समर्थन करता है का क्लोन बनाने के लिए।


यदि कोई इसे पढ़ता है तो यह महसूस नहीं होता है कि किसी ऑब्जेक्ट को किसी अन्य चर पर असाइन करने से जावास्क्रिप्ट में एक प्रतिलिपि नहीं होती है। जावास्क्रिप्ट में असाइनमेंट एक ही ऑब्जेक्ट के लिए पॉइंटर संदर्भ सेट करना है।प्रत्येक चर तो समान ही अंतर्निहित वस्तु इतनी वस्तु को संशोधित करने के माध्यम से या तो चर इस तरह दोनों ही मामलों में एक ही वस्तु को संशोधित समाप्त होता है के लिए अंक:

var obj = { 
    list: [1,2,3], 
    items: [{language: "English", greeting: "hello"}, 
      {language: "Spanish", greeting: "hola"}, 
      {language: "French", greeting: "bonjour"}] 
} 

var copy = obj; 

// modify copy 
copy.items[0].greeting = "Yo"; 

// both obj and copy refer to the exact same object 
console.log(obj.items[0].greeting); // "Yo" 
console.log(copy.items[0].greeting); // "Yo" 

इस प्रकार, एक वस्तु का एक वास्तविक गहरी प्रतिलिपि बनाने के लिए समय-समय पर की जरूरत है।

+0

यह भी ध्यान देने योग्य है कि यह परिपत्र संदर्भों के साथ काम नहीं करता है और उसी वस्तु के कई संदर्भों को संरक्षित नहीं करता है (यानी '[ए, ए] '' ए, बी] ') बन जाएगा। –

+2

@ फ़ेलिक्सक्लिंग - उत्तर में आपकी अतिरिक्त चेतावनियां जोड़ दी गईं। – jfriend00

+1

उन मामलों के लिए जहां आपको ऑब्जेक्ट के गहरे क्लोन की आवश्यकता है, यह जवाब देखें: http://stackoverflow.com/a/13333781/560114 –

-1

यदि प्रोटोटाइप से विधियों को हटाना आप चाहते हैं, तो एक नई वस्तु बनाने और पुराने ऑब्जेक्ट की सभी संपत्तियों को स्थानांतरित करने पर विचार करें।

हैं गुण है कि एक समारोह कर रहे हैं बाहर अलग करना है कि तुम क्या वस्तु के माध्यम से चाहते हैं, पाश और देखें कि क्या संपत्ति एक समारोह है:

for(key in ob) 
{ 
    if(typeof ob[key] === 'function') 
    { 
     delete ob[key]; 
    } 
} 

या शायद तुम क्या पूरा करने के लिए आशा है कि उन दोनों का संयोजन है ।

संबंधित मुद्दे