JavaScript에서 [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] 왜?
shabunc

9
이번 주 [1,2] + [3,4]가 alert ( 'crap') 이후 파이어 버그에서 가장 많이 평가 된 표현이라고 생각합니다.
okeen

6
웃고 싶다 ? [] + [], {} + [], {} + {} 및 [] + {} 시도
Intrepidd

1
@shabunc - 왜주의를 설명하는 [5,6,7][1,2]것입니다 7그것은 두 번째 배열의 마지막 항목을 사용하기 때문에. Oo
vsync

답변:


518

+연산자는 배열에 정의되지 않는다 .

Javascript 는 배열을 문자열로 변환하고 배열로 연결합니다.

 

최신 정보

이 질문과 결과적으로 제 답변이 많은 관심을 받고 있기 때문에 운영자가 일반적으로 어떻게 행동하는지에 대한 개요 를 갖는 것이 유용하고 적절하다고 생각했습니다 +.

그래서, 여기에 간다.

E4X 및 구현 별 항목을 제외하고 Javascript (ES5 기준)에는 6 가지 기본 제공 데이터 유형이 있습니다 .

  1. 찾으시는 주소가 없습니다
  2. 없는
  3. 부울
  4. 번호
  5. 목적

Null과 호출 가능한 Object에 대해 typeof 다소 혼란스럽게 반환 하지만 Null은 실제로 Object가 아니며 엄격하게 말하면 사양을 준수하는 Javascript 구현에서 모든 함수는 Object로 간주됩니다.objectfunction

맞습니다. 자바 스크립트에는 기본 배열없습니다 . Array통증을 완화하기 위해 구문 설탕으로 불리는 개체의 인스턴스 만 .

같은 기관 래퍼 혼란을 더 추가 new Number(5), new Boolean(true)new String("abc")의 모두 object유형, 하나는 예상대로되지 숫자, 부울 또는 문자열. 그럼에도 불구하고 산술 연산자에 대한 NumberBoolean번호와 같은 동작합니다.

쉬운가요? 그 모든 것을 벗어나면 개요 자체로 넘어갈 수 있습니다.

+피연산자 유형별로 다른 결과 유형

            || 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, a는 number, 평가는 o + '2'생산 '42'a는 string.

개요 테이블이 생성 된 방법을 보려면 http://jsfiddle.net/1obxuc7m/을 방문하십시오.


244

JavaScript +연산자는 두 가지 숫자를 추가하거나 두 문자열을 결합하는 두 가지 목적이 있습니다. 배열에 대한 특정 동작이 없으므로 배열을 문자열로 변환 한 다음 결합합니다.

두 개의 배열을 결합하여 새 배열을 생성하려면 대신 메소드 를 사용 하십시오.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에 정의되어 있습니다 .

11.6.1 덧셈 연산자 (+)

더하기 연산자는 문자열 연결 또는 숫자 추가를 수행합니다. 생산 AdditiveExpression : AdditiveExpression + MultiplicativeExpression은 다음과 같이 평가됩니다.

  1. lref평가 결과를 보자 AdditiveExpression.
  2. 하자 lvalGetValue(lref).
  3. rref평가 결과를 보자 MultiplicativeExpression.
  4. 하자 rvalGetValue(rref).
  5. 하자 lprimToPrimitive(lval).
  6. 하자 rprimToPrimitive(rval).
  7. 경우 Type(lprim)입니다 String또는 Type(rprim)이다 String후,
    1. 연결 한 ToString(lprim)뒤에 나오는 문자열을 반환합니다.ToString(rprim)
  8. 더하기 연산을 적용한 결과를 ToNumber(lprim)및에 반환합니다 ToNumber(rprim). 아래의 참고 사항을 참조하십시오 11.6.3.

각 피연산자가 변환 된 것을 볼 수 있습니다 ToPrimitive. 더 자세히 읽으면 ToPrimitive항상 배열을 문자열로 변환 하여이 결과를 생성 한다는 것을 알 수 있습니다.


7
이 답변은 문제를 설명 할뿐만 아니라 올바르게 수행하는 방법도 설명합니다.
schnaader

3
여기에 약간의 tmi가 있지만 나는 schnaader에 동의합니다. 가장 좋은 답변은 요청 된 문제 / 오류 / 동작을 설명하고 의도 한 결과를 생성하는 방법을 보여줍니다. +1
matthewdunnam

1
Array.prototype.push.apply(data, [3, 4])대신 더 자세한 정보를 사용 data.concat([3,4])하시겠습니까?
evilcelery

5
@evilcelery : 그들은 다른 목적을 제공합니다. 새로운 배열을 concat생성하면 호출 시간이 길어 기존 배열을 효율적으로 확장합니다 .
Jeremy Banks

1
[].push.apply(data, [3,4])약간 덜 장황하게 사용할 수 있습니다 . 또한 이는의 가치를 바꾸는 다른 사람들에게 저항력이 있습니다 Array.
Sam Tobin-Hochstadt

43

배열 을 마치 문자열 인 것처럼 추가합니다 .

첫 번째 배열의 문자열 표현은 "1,2" 이고 두 번째 배열은 "3,4" 입니다. 따라서 +부호가 발견되면 배열을 합한 다음 문자열로 연결할 수 없습니다.


그렇습니다, 그것은 마음에 오는 최초의 독특한 설명이지만, 그렇게 이상한 행동이 아닙니까? 어쩌면 어둡고 알 수없는 작업 / 변환이 수행되고 내부를 알고 싶습니다. : P
okeen

40

+concats 문자열, 그래서 문자열 배열을 변환합니다.

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

배열을 결합하려면을 사용하십시오 concat.

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

21

JavaScript에서 이진 덧셈 연산자 ( +)는 숫자 덧셈과 문자열 연결을 모두 수행합니다. 그러나 첫 번째 인수가 숫자이거나 문자열이 아닌 경우 문자열로 변환하여 ( " 1,2") 두 번째 " 3,4"와 동일하게 수행하여 " "로 연결합니다 1,23,4.

대신 배열의 "concat"메소드를 사용해보십시오.

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

19

개별 배열을 문자열로 변환 한 다음 문자열을 결합합니다.


14

JavaScript가 배열을 문자열로 바꾸고 함께 결합하는 것처럼 보입니다. 튜플을 함께 추가하려면 루프 또는 맵 기능을 사용해야합니다.


14

[1,2]+[3,4] JavaScript에서 다음을 평가하는 것과 같습니다.

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
hehe, 그것은 항상 내가 요구 한 것을한다. 문제는 좋은 질문을하는 것입니다. 흥미로운 점은 배열을 추가 할 때 배열의 toString () 해석입니다.
okeen


8

+ 연산자는 피연산자가 숫자가 아닌 경우 문자열이라고 가정하기 때문입니다. 따라서 먼저 문자열로 변환하고 숫자가 아닌 경우 최종 결과를 제공하기 위해 연결합니다. 또한 배열을 지원하지 않습니다.


2
+ 연산자는 1 + 1 == 2이므로 피연산자가 문자열이라고 가정 할 수 없습니다. 배열에 대해 '+'가 정의되어 있지 않기 때문에 toString-s입니다.
okeen

0

여기의 일부 답변은 예기치 않은 원하지 않는 출력 ( '1,23,4')이 발생하는 방법을 설명하고 일부는 예상되는 원하는 출력 ( [1,2,3,4]), 즉 배열 연결 이라고 생각하는 것을 얻는 방법을 설명했습니다 . 그러나 원래의 질문에 단순히 "배열의 요소를 다른 배열에 추가하고 싶었습니다 ..."라고 말했기 때문에 예상되는 원하는 출력의 특성은 실제로 다소 모호합니다. 즉, 어레이 연결을 의미하지만, 수 (예를 들면 평균 튜플 첨가 여기여기에 , 즉, 예를 들면, 초에 대응하는 요소의 스칼라 값으로 하나 개의 어레이에서 소자의 스칼라 값을 추가 조합) [1,2][3,4]얻었다 [4,6].

두 어레이 모두 동일한 arity / length를 가정하면 다음과 같은 간단한 솔루션이 있습니다.

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]

...하지만 변수 a를 Array에서 String으로 변환합니다! 명심 해.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.