2015-05-30 6 views
8

जब सरणी किसी अन्य चर को सौंपा जाता है, तो संदर्भ मानों के विपरीत पारित किया जाता है। जब आप == ऑपरेटर का उपयोग दो सरणियों की तुलना इस बात की पुष्टि की है और यह रिटर्न trueArrays की समझ के साथ मुझे क्या याद आ रही है?

var a = [[1,2],[3,4],[5,6]]; 
var b = a; // b = [[1,2],[3,4],[5,6]] 
var c = [].concat(a); // c = [[1,2],[3,4],[5,6]] 

a == b; //true 
a == c; //false 
ऊपर आदानों के साथ

, जब मैं सरणी b संशोधित करने, यह सरणी a, लेकिन नहीं c mutates।

b.push([7,8]); // b = [[1,2],[3,4],[5,6], [7,8]] 
a; //a = [[1,2],[3,4],[5,6], [7,8]] 
c; //c = [[1,2],[3,4],[5,6]] 

लेकिन जब मैं नीचे करता हूं, तो यह c को बदलता है।

b[0].push(5); // b = [[1,2,5],[3,4],[5,6], [7,8]] 
a; //a = [[1,2,5],[3,4],[5,6], [7,8]] 
c; //c = [[1,2,5],[3,4],[5,6]] 

ऐसा क्यों होता है? यह व्यवहार सरणी विधियों के उपयोग के साथ होता है जो सरणी को म्यूट करता है।

उत्तर

14

.concat() एक उथली प्रतिलिपि करता है। तो पंक्ति के बाद:

var c = [].concat(a); 

c और a संदर्भ अलग सरणियों, लेकिन c[0] और b[0] और a[0] सभी संदर्भ में एक ही सरणी।

MDN से हवाला देते हुए:

concat प्रतियां नई सरणी में संदर्भ आपत्ति है। मूल और नई दोनों सरणी एक ही वस्तु को संदर्भित करती हैं। यही है, यदि एक संदर्भित वस्तु संशोधित की जाती है, तो परिवर्तन नए और मूल दोनों arrays के लिए दृश्यमान होते हैं।

+0

+1, यह उत्तर है। क्या आपको लगता है कि एक सरणी (या किसी अन्य वस्तु) की * गहरी * प्रतिलिपि बनाने के तरीके को शामिल करना अच्छा विचार होगा? (jQuery '.extend()' या lodash '.deepClone()'?) – bardzusny

+1

@bardzusny पहले से ही stackoverflow पर बहुत सारे जवाब हैं। – Leo

+0

धन्यवाद nnnnnn, जो व्यवहार को समझाता है। @bardzusny के रूप में, क्या कोई किसी भी अंतर्निहित विधियों या पुस्तकालयों का सुझाव दे सकता है जो सरणी की गहरी प्रतिलिपि करता है? – Harish

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