जावास्क्रिप्ट में [1,2] + [3,4] = "1,23,4" क्यों है?


405

मैं एक सरणी के तत्वों को दूसरे में जोड़ना चाहता था, इसलिए मैंने यह कोशिश की:

[1,2] + [3,4]

इसके साथ जवाब दिया:

"1,23,4"

क्या हो रहा है?


1
यहाँ इस विषय से संबंधित एक प्रश्न है: stackoverflow.com/questions/1724255/why-does-2-2-in-javascript
Xavi

29
आह-हा-हा, सैडिस्ट साक्षात्कारकर्ता कुछ भी पूछ सकते हैं जैसे - यह क्या लौटाएगा [1,2] + [5,6,7] [1,2]। क्यों?
शबूनक

9
मुझे लगता है कि [१,२] + [३,४] इस सप्ताह फायरबग में सबसे अधिक मूल्यांकन किया गया है, अलर्ट ('बकवास') के बाद।
okeen

6
हँसना चाहता हूँ ? कोशिश करो [] + [], {} + [], {} + {}, और [] + {}
निश्चय

1
@shabunc - देखभाल समझाने के लिए क्यों [5,6,7][1,2]है 7, क्योंकि यह दूसरी सरणी में अंतिम आइटम का उपयोग करता है। Oo
vsync

जवाबों:


518

+ऑपरेटर सरणियों के लिए निर्धारित नहीं है

क्या होता है कि जावास्क्रिप्ट सरणियों को तार में परिवर्तित करता है और उन को समेटता है।

 

अपडेट करें

चूँकि यह प्रश्न और फलस्वरूप मेरे उत्तर पर बहुत अधिक ध्यान दिया जा रहा है, मुझे लगा कि ऑपरेटर सामान्य रूप में भी कैसे व्यवहार करता है, इस बारे में अवलोकन करना उपयोगी और प्रासंगिक होगा +

तो, यहाँ यह जाता है।

ई 4 एक्स और कार्यान्वयन-विशिष्ट सामान को छोड़कर, जावास्क्रिप्ट (ईएस 5 के रूप में) में 6 अंतर्निहित डेटा प्रकार हैं :

  1. अपरिभाषित
  2. शून्य
  3. बूलियन
  4. संख्या
  5. तार
  6. वस्तु

ध्यान दें कि यद्यपि typeof कुछ भ्रमित रूप object से नल के लिए और functionकॉल करने योग्य वस्तुओं के लिए, नल वास्तव में एक वस्तु नहीं है और सख्ती से बोल रहा है, विनिर्देश-अनुरूप जावास्क्रिप्ट कार्यान्वयन में सभी कार्यों को ऑब्जेक्ट माना जाता है।

यह सही है - जावास्क्रिप्ट में कोई आदिम सरणियाँ नहीं हैं जैसे; किसी वस्तु के केवल उदाहरणों Arrayने दर्द को कम करने के लिए कुछ सिंटैक्टिक चीनी के साथ बुलाया ।

जैसे संस्थाओं आवरण, भ्रम के लिए और अधिक जोड़ने से new Number(5), new Boolean(true)और new String("abc")के सभी कर रहे हैं objectप्रकार, नहीं नंबर, बूलियन्स या तार के रूप में एक उम्मीद कर सकते हैं। फिर भी अंकगणितीय ऑपरेटरों के लिए Numberऔर Booleanसंख्याओं के रूप में व्यवहार करते हैं।

आसान है, है ना? उस रास्ते से सभी के साथ, हम अवलोकन पर आगे बढ़ सकते हैं।

विभिन्न प्रकार के +ऑपरेंड प्रकार के परिणाम

            || undefined | null   | boolean | number | string | object |
=========================================================================
 undefined  || number    | number | number  | number | string | string | 
 null       || number    | number | number  | number | string | string | 
 boolean    || number    | number | number  | number | string | string | 
 number     || number    | number | number  | number | string | string | 
 string     || string    | string | string  | string | string | string | 
 object     || string    | string | string  | string | string | string | 

* Chrome13, FF6, Opera11 और IE9 पर लागू होता है। अन्य ब्राउज़रों और संस्करणों की जांच करना पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है।

नोट: जैसा कि CMS द्वारा इंगित किया गया है , वस्तुओं के कुछ मामलों के लिए Number, Booleanऔर कस्टम वाले +ऑपरेटर जरूरी नहीं कि एक स्ट्रिंग परिणाम उत्पन्न करें। यह आदिम रूपांतरण के लिए वस्तु के कार्यान्वयन के आधार पर भिन्न हो सकता है। उदाहरण के लिए var o = { valueOf:function () { return 4; } };मूल्यांकन का o + 2;उत्पादन 6, एक number, मूल्यांकन का o + '2'उत्पादन '42', एक string

यह देखने के लिए कि अवलोकन तालिका कैसे तैयार की गई थी http://jsfiddle.net/1obxuc7m/


244

जावास्क्रिप्ट के +ऑपरेटर के दो उद्देश्य हैं: दो संख्याओं को जोड़ना, या दो तारों का जुड़ना। इसमें सरणियों के लिए एक विशिष्ट व्यवहार नहीं है, इसलिए यह उन्हें तार में परिवर्तित कर रहा है और फिर उन्हें जोड़ रहा है।

यदि आप एक नया निर्माण करने के लिए दो सरणियों में शामिल होना चाहते हैं, तो.concat इसके बजाय विधि का उपयोग करें :

[1, 2].concat([3, 4]) // [1, 2, 3, 4]

यदि आप कुशलतापूर्वक सभी तत्वों को एक सरणी से दूसरे में जोड़ना चाहते हैं, तो आपको .push विधि का उपयोग करने की आवश्यकता है :

var data = [1, 2];

// ES6+:
data.push(...[3, 4]);
// or legacy:
Array.prototype.push.apply(data, [3, 4]);

// data is now [1, 2, 3, 4]

+ऑपरेटर का व्यवहार ECMA-262 5e धारा 11.6.1 में परिभाषित किया गया है :

११.६.१ अतिरिक्त संचालक (+)

इसके अलावा ऑपरेटर या तो स्ट्रिंग समाकलन या संख्यात्मक जोड़ करता है। उत्पादन AdditiveExpression : AdditiveExpression + MultiplicativeExpressionका मूल्यांकन निम्नानुसार किया जाता है:

  1. आज्ञा देना lrefमूल्यांकन का परिणाम है AdditiveExpression
  2. चलो lval हो GetValue(lref)
  3. चलो rrefमूल्यांकन का परिणाम है MultiplicativeExpression
  4. चलो rval हो GetValue(rref)
  5. चलो lprim हो ToPrimitive(lval)
  6. चलो rprim हो ToPrimitive(rval)
  7. अगर Type(lprim)है StringयाType(rprim) है Stringतो
    1. स्ट्रिंग को वापस लौटाएं जो ToString(lprim)बाद में सहमति का परिणाम हैToString(rprim)
  8. करने के लिए ToNumber(lprim)और इसके अलावा ऑपरेशन को लागू करने का परिणाम लौटाएं ToNumber(rprim)। नीचे नोट 11.6.3 देखें।

आप देख सकते हैं कि प्रत्येक ऑपरेंड परिवर्तित हो गया है ToPrimitive। आगे पढ़कर हम पा सकते हैं कि ToPrimitiveहमेशा एरेज़ को स्ट्रिंग्स में परिवर्तित किया जाएगा, जिससे यह परिणाम होगा।


7
+1 यह उत्तर न केवल समस्या की व्याख्या करता है, बल्कि यह भी बताता है कि इसे सही कैसे किया जाए।
श्नाडर

3
यहाँ एक छोटा सा tmi है, लेकिन मैं schnaader से सहमत हूँ। सबसे अच्छा उत्तर उस समस्या / त्रुटि / व्यवहार की व्याख्या करता है जिसके बारे में पूछा जा रहा है, यह दिखाता है कि इच्छित परिणाम कैसे उत्पन्न किया जाए। +1
मैथ्यू डनडम

1
आप Array.prototype.push.apply(data, [3, 4])इसके बजाय अधिक क्रिया का उपयोग क्यों करेंगे data.concat([3,4])?
बंडसेलरी

5
@ स्टीविलरी: वे विभिन्न उद्देश्यों की पूर्ति करते हैं। concatएक नया एरे पैदा करता है , लंबे समय तक कॉल कुशलता से एक मौजूदा एरे को बढ़ाता है ।
जेरेमी बैंक्स

1
आप [].push.apply(data, [3,4])थोड़ी कम वाचालता के लिए उपयोग कर सकते हैं । इसके अलावा, यह गारंटी दी जाती है कि अन्य लोगों के लिए प्रतिरोधी मूल्य बदल रहा है Array
सैम टोबिन-होचस्टाट

43

यह दोनों को जोड़ता है सरणियों को जैसे कि वे तार थे ।

पहली सरणी के लिए स्ट्रिंग प्रतिनिधित्व "1,2" होगा और दूसरा "3,4" होगा । इसलिए जब +संकेत पाया जाता है, तो यह एरेज़ को योग नहीं करता है और फिर उन्हें स्ट्रिंग्स के रूप में समेटता है।


हां, यह पहली और अनोखी व्याख्या है जो मन में आती है लेकिन, क्या यह बहुत अजीब व्यवहार नहीं है? शायद वहाँ कुछ अंधेरा, अनजाने ऑपरेशन / परिवर्तन किया जा रहा है, और मैं
इनर

40

+Concats तार, तो यह तार करने के लिए सरणियों बदल देता है।

[1,2] + [3,4]
'1,2' + '3,4'
1,23,4

सरणियों को संयोजित करने के लिए, उपयोग करें concat

[1,2].concat([3,4])
[1,2,3,4]

21

जावास्क्रिप्ट में, द्विआधारी जोड़ ऑपरेटर ( +) संख्यात्मक जोड़ और स्ट्रिंग संयोजन दोनों करता है। हालाँकि, जब यह पहला तर्क न तो एक संख्या है और न ही एक स्ट्रिंग है तो यह इसे एक स्ट्रिंग में परिवर्तित करता है (इसलिए " 1,2") तो यह दूसरे " 3,4" के साथ भी ऐसा ही करता है और उन्हें " 1,23,4" में समेट देता है ।

इसके बजाय Arrays की "कॉन्कैट" विधि का उपयोग करने का प्रयास करें:

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

19

यह व्यक्तिगत सरणियों को स्ट्रिंग्स में परिवर्तित कर रहा है, फिर स्ट्रिंग्स के संयोजन।


14

ऐसा लगता है कि जावास्क्रिप्ट आपके सरणियों को तार में बदल रहा है और उन्हें एक साथ जोड़ रहा है। यदि आप एक साथ ट्यूपल्स जोड़ना चाहते हैं, तो आपको एक लूप या मैप फ़ंक्शन का उपयोग करना होगा।


14

[1,2]+[3,4] जावास्क्रिप्ट में मूल्यांकन के रूप में ही है:

new Array( [1,2] ).toString() + new Array( [3,4] ).toString();

और इसलिए आपकी समस्या को हल करने के लिए, सबसे अच्छी बात यह होगी कि दो ऐरे को एक जगह पर जोड़ा जाए या एक नया एरे बनाए बिना:

var a=[1,2];
var b=[3,4];
a.push.apply(a, b);

12

यह वही कर रहा है जो आपने इसे करने के लिए कहा था।

आप जो जोड़ रहे हैं वह सरणी संदर्भ हैं (जो JS स्ट्रिंग्स में कनवर्ट करता है), संख्या नहीं जैसा कि लगता है। यह एक साथ तार जोड़ने जैसा है: "hello " + "world"="hello world"


5
हे, यह हमेशा वही करता है जो मैंने पूछा था। समस्या यह है कि अच्छा सवाल पूछा जाए। जब आप उन्हें जोड़ते हैं तो सरणियों की स्ट्रैसिंग () व्याख्या क्या होती है।
okeen

8

अच्छा होगा यदि आप जावास्क्रिप्ट में ऑपरेटरों को ओवरलोड कर सकते हैं, लेकिन आप नहीं कर सकते: क्या मैं जावास्क्रिप्ट में कस्टम ऑपरेटर ओवरलोड को परिभाषित कर सकता हूं? आप केवल "==" ऑपरेटर को हैक कर सकते हैं जो तुलना करने से पहले तार में परिवर्तित हो जाता है: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx


8

ऐसा इसलिए है क्योंकि, + ऑपरेटर मानता है कि ऑपरेंड स्ट्रिंग हैं, यदि वे संख्या नहीं हैं। इसलिए, यह पहले उन्हें अंतिम परिणाम देने के लिए स्ट्रिंग और कंसर्ट में परिवर्तित करता है, अगर इसकी संख्या नहीं है। इसके अलावा, यह सरणियों का समर्थन नहीं करता है।


2
+ ऑपरेटर नहीं मान सकता है कि ऑपरेंड स्ट्रिंग्स हैं, क्योंकि 1 + 1 == 2, अन्य के बीच। ऐसा इसलिए है क्योंकि सरणियों के लिए '+' परिभाषित नहीं है, इसलिए यह उन्हें -String-s।
बजे

0

यहाँ कुछ उत्तरों ने समझाया है कि अप्रत्याशित अवांछित उत्पादन कैसे '1,23,4'होता है ( ) होता है और कुछ ने समझाया है कि कैसे प्राप्त किया जा सकता है जो वे अपेक्षित वांछित आउटपुट ( [1,2,3,4]), अर्थात सरणी संयोजन के रूप में मानते हैं । हालांकि, अपेक्षित वांछित आउटपुट की प्रकृति वास्तव में कुछ अस्पष्ट है, क्योंकि मूल प्रश्न में कहा गया है "मैं एक सरणी के तत्वों को दूसरे में जोड़ना चाहता था ..."। इसका मतलब है कि एरे के संयोजन का मतलब हो सकता है, लेकिन इसका मतलब यह भी हो सकता है कि इसके अलावा (जैसे यहाँ और यहाँ ), अर्थात एक एरे में तत्वों के अदिश मानों को एक एरे में तत्संबंधी तत्वों के अदिश मानों में जोड़ना, जैसे संयोजन [1,2]और [3,4]प्राप्त करना[4,6]

दोनों सरणियों को समान / लंबाई मानकर, यहाँ एक सरल उपाय दिया गया है:

const arr1 = [1, 2];
const arr2 = [3, 4];

const add = (a1, a2) => a1.map((e, i) => e + a2[i]);

console.log(add(arr1, arr2)); // ==> [4, 6]


-1

केवल एक सरल "+" चिह्न का उपयोग करने वाला एक और परिणाम होगा:

[1,2]+','+[3,4] === [1,2,3,4]

तो इस तरह से कुछ काम करना चाहिए (लेकिन!):

var a=[1,2];
var b=[3,4];
a=a+','+b; // [1,2,3,4]

... लेकिन यह चर को ऐरे से स्ट्रिंग में बदल देगा! इसे ध्यान में रखें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.