2017-06-21 9 views
5

मैं किसी ऑब्जेक्ट को गहरे क्लोन करने की कोशिश कर रहा हूं, "ए" कहें के = JSON.parse (JSON.stringify (ए))। यह महत्वपूर्ण है कि मैं स्ट्रिंगफ़ाई तरीके का उपयोग करता हूं, क्योंकि मैं ऑब्जेक्ट को फ़ाइल में सहेजने की कोशिश कर रहा हूं और फिर उससे लोड करता हूं।जावास्क्रिप्ट: JSON.parse के साथ एक स्ट्रिंग ऑब्जेक्ट को पार्स करना संदर्भ

var obj={}; 
 
obj.importantProperty={s:2}; 
 
obj.c=obj.importantProperty; 
 
obj.d=obj.importantProperty; 
 
console.log(obj.c === obj.d); // Returns true 
 

 
var cloned = JSON.parse(JSON.stringify(obj)); 
 
console.log(cloned.c === cloned.d); // Returns false
मैं ऊपर के उदाहरण वे नहीं हैं में जब JSON.parse का उपयोग कर के संदर्भ रखा जाना करने की जरूरत है,:

मैं जो कि नीचे बताया गया है क्लोन वस्तु पर संदर्भ के साथ एक समस्या पर ठोकर खाई । मेरी परियोजना में वस्तु अधिक जटिल है, लेकिन अंत में यह उपरोक्त उदाहरण के लिए नीचे आता है। जो मुझे मदद करता है यह :) का उपयोग

+3

'JSON.parse' स्ट्रिंग प्रस्तुति से एक नई संरचना बनाता है। ऐसा कोई तरीका नहीं है कि यह समझ सके कि दो वस्तुएं समान हैं। –

+0

और भी अधिक: 'क्लोन === obj -> false'। –

+0

क्लोन === ओबीजे -> झूठा सामान्य है, क्योंकि क्लोन ऑब्जेक्ट एक गहरा क्लोन है, यानी अलग संदर्भ। आपके जवाब के लिए धन्यवाद। –

उत्तर

0

इस तरह कुछ करने का उचित तरीका आम संदर्भित ऑब्जेक्ट को अलग से स्टोर करना होगा और इसे आईडी द्वारा संदर्भित करना होगा।

उदाहरण के लिए, आप एक सरणी में अपने importantProperty वस्तुओं पकड़ और आईडी के रूप में इंडेक्स का उपयोग कर सकते हैं:

var stringified = JSON.stringify(obj, function(key, value) { 
    if (key) { 
    return importantProperties.indexOf(value); 
    } 
    return value; 
}); 
console.log(stringified); 
// prints {"importantProperty":1,"c":1,"d":1} 
:

var importantProperties = [ 
    { s: 1 }, 
    { s: 2 }, 
    { s: 3 } 
]; 

var obj = {}; 
obj.importantProperty = importantProperties[1]; 
obj.c = obj.importantProperty; 
obj.d = obj.importantProperty; 

फिर जब आप वस्तु stringify आप अपने सूचकांक के साथ संदर्भित वस्तु की जगह

और फिर जब आप पार्स आप बस प्रक्रिया को उल्टा पुनर्जीवित करने के लिए संदर्भ:

var parsed = JSON.parse(stringified, function(key, value) { 
    if (key) { 
    return importantProperties[value]; 
    } 
    return value; 
}); 
console.log(parsed.c === parsed.d && parsed.d === parsed.importantProperty); 
// prints true 

अब, ऊपर दिया गया उदाहरण इस उदाहरण के तहत आपके उदाहरण कोड के लिए काम करता है कि obj में सभी गुण importantProperties सरणी से एक वस्तु है। यदि यह मामला नहीं है और यह केवल कुछ गुण हैं जो importantProperties ऑब्जेक्ट है, तो आपको उस स्थान को बदलने/पुनर्जीवित करने की आवश्यकता है।
मान लिया जाये कि केवल "importantProperty", "सी" और "डी" गुण इस तरह की वस्तुओं रहे हैं:
बजाय if (['importantProperty', 'c', 'd'].includes(key)) सिर्फ if (key)

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

// Replacing 
JSON.stringify(obj, function(k, value) { 
    if (importantProperties.includes(value)) { 
    return 'ImportantProperty[' 
     + importantProperties.indexOf(value) 
     + ']'; 
    } 
    return value; 
}); 

// Reviving 
JSON.parse(stringified, function(k, value) { 
    if (/^ImportantProperty\[\d+\]$/.test(value)) { 
    var index = Number(value.match(/\d+/)[0]); 
    return importantProperties[index]; 
    } 
    return value; 
}); 
0

यह JSON का उपयोग कर अपने वांछित परिणाम प्राप्त क्योंकि JSON प्रारूप केवल डेटा प्रकार के एक सीमित राशि (http://json.org/) शामिल कर सकते हैं और जब आप एक stringify करना असंभव है किसी को भी पहले से

धन्यवाद JSON पर ऑब्जेक्ट कुछ जानकारी खो जाती है।

शायद कुछ अन्य प्रकार की धारावाहिक तकनीक है, लेकिन मैं आपको डेटा स्टोर करने के लिए एक और दृष्टिकोण की तलाश करने की सलाह दूंगा।

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