Development Tip

JavaScript가 문자열과 숫자 사이의 더하기 및 빼기 연산자를 다르게 처리하는 이유는 무엇입니까?

yourdevel 2020. 11. 19. 22:09
반응형

JavaScript가 문자열과 숫자 사이의 더하기 및 빼기 연산자를 다르게 처리하는 이유는 무엇입니까?


JavaScript가 왜 이런 식으로 작동하는지 이해하지 못합니다.

console.log("1" + 1);
console.log("1" - 1);

첫 번째 줄은 11을, 두 번째 줄은 0을 인쇄합니다. JavaScript는 첫 번째 줄을 문자열로, 두 번째 줄을 숫자로 처리하는 이유는 무엇입니까?


문자열 연결이 수행 +되므로 Javascript는 첫 번째 숫자 1을 문자열로 변환하고 "1"과 "1"을 연결하여 "11"을 만듭니다.

문자열에서 빼기를 수행 할 수 없으므로 Javascript는 두 번째 "1"을 숫자로 변환하고 1에서 1을 빼서 0이됩니다.


+모호합니다. "연결" 또는 "추가"를 의미 할 수 있습니다 . 한쪽이 문자열이기 때문에 "연결"을 의미하므로 결과는 11입니다 (어린 시절 제가 가장 좋아하는 농담 중 하나였습니다. 그리고 "1 + 1 = 창"은 다음과 같습니다. 시각적 도시 : │┼│ ニ ⊞)

-그러나 단 하나의 의미가 있습니다 : 빼기. 그래서 뺍니다.

이런 종류의 문제는 PHP와 같은 다른 언어에서는 존재하지 않습니다. 여기서 "concatenate"가 .대신 사용 +되므로 모호하지 않습니다. MySQL과 같은 다른 언어에는 연결 연산자조차없는 대신 CONCAT(a,b,c...).


때문에 사양이 명시 적으로 이렇게 알려줍니다. Page 75. 11.6.1 단계 5-8과 11.6.2 단계 5-7의 차이점에 유의하십시오.

11.6.1-덧셈 연산자 작동 방식 설명

1-4. ...

5. lprim을 ToPrimitive (lval)로 둡니다.

6. rprim을 ToPrimitive (rval)로 둡니다.

7. Type (lprim)이 String이거나 Type (rprim)이 String이면

7a. ToString (lprim) 다음에 ToString (rprim)을 연결 한 결과 인 String을 반환합니다.

8. ToNumber (lprim) 및 ToNumber (rprim)에 더하기 연산을 적용한 결과를 반환합니다.

11.6.2-빼기 연산자 작동 방식 설명

1-4. ...

5. lnum을 ToNumber (lval)라고합니다.

6. rnum을 ToNumber (rval)라고합니다.

7. lnum 및 rnum에 빼기 연산을 적용한 결과를 반환합니다.

요약 힌트없이 프리미티브 값으로 변환 할 때 피연산자 중 하나가 갑자기 문자열이된다면 덧셈의 경우 두 번째 피연산자도 문자열로 변환됩니다. 빼기의 경우 두 피연산자가 숫자로 변환됩니다.


+둘 다 덧셈 연산자 수치 변수 및 연결 연산자 문자열이.

뒤에 문자열이있을 때마다 +Javascript +는를 연결 연산자로 사용 하고 문자열 주위에 가능한 한 많은 용어를 변환 (입력)하여 연결할 수 있습니다. 그것은 Javascript의 동작입니다. (시도 console.log(23 + 2 + "." + 1 + 5 + "02" + 02);하면 결과가 표시 25.15022됩니다. 숫자 022연결되기 전에 문자열에 입력되었습니다 .

-빼기 연산자 만 될 수 있으므로 문자열이 주어지면 암시 적으로 문자열 유형을 "1"숫자로 변경합니다 1. 그렇게하지 않으면 말이되지 않을 것입니다 "1" - 1. 시도 console.log(23 + 2 + 1 + 5 - "02" + 03);하면 32를 02얻게됩니다 2. 문자열 은 숫자로 변환됩니다 . 뒤에있는 용어 -는 숫자로 변환 될 수 있어야합니다. 시도 console.log(23 - 2 - "." - 1 - 5 - 02 - "02");하면 NaN반환됩니다.

더 중요한 것은 시도 console.log(23 + 2 + "." + 1 + 5 - "02" + 03);하면을 출력합니다 26.15. 여기서 이전의 모든 -것은 문자열로 처리됩니다 (문자열이 포함되어 "."있고 다음 용어 -가 숫자로 처리되기 때문).


JavaScript **에는 전용 문자열 연결 연산자가 없습니다. 더하기 연산자 +는 피연산자 유형에 따라 문자열 연결 또는 더하기를 수행합니다.

"1" +  1  // "11"
 1  + "1" // "11"
 1  +  1  // 2

연결 (내 생각에)의 반대는 없으며 빼기 연산자 -는 피연산자의 유형에 관계없이 빼기 만 수행합니다.

"1" -  1  // 0
 1  - "1" // 0
 1  -  1  // 0
"a" -  1  // NaN

** .PHP의 &연산자와 VB의 연산자는 전용 문자열 연결 연산자입니다.


표준 EcmaScript 262에 따르면 +-연산자는 문자열이 관련 될 때 다르게 작동합니다. 첫 번째는 모든 값을 문자열로 변환합니다. 두 번째는 모든 값을 숫자로 변환합니다.

표준에서 :

Type (lprim)이 String이거나 Type (rprim)이 String이면 ToString (lprim)과 ToString (rprim)을 연결 한 결과 인 String을 반환합니다.

이 규칙은 표현식에 문자열 값이있는 경우 +연산에 관련된 모든 값 이 문자열로 변환 됨을 의미 합니다. JavaScript에서 +연산자가 문자열과 함께 사용되는 경우이를 연결합니다. 이것이 console.log("5"+1)"51"을 반환하는 이유 입니다. 1문자열로 변환 된 다음 "5"+ "1"이 함께 연결됩니다.

그럼에도 불구하고 위의 규칙은 -운영자에게 적용되지 않습니다 . 을 사용하면 -모든 값이 표준에 따라 숫자로 변환됩니다 (아래 참조). 따라서이 경우 "5"는로 변환 된 5다음 1뺍니다.

표준에서 :

5 lnum을 ToNumber (lval)라고합니다.

6 rnum을 ToNumber (rval)라고합니다.


표준 EcmaScript 262의 연산자 정의.

연산자 + : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 연산자 + 정의

운영자- : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2 연산자-정의


더하기와 문자열 ""사용 하면 연결을 수행하기 때문에 기본적으로 문자열 을 반환합니다.

typeof ("" + 1 + 0)  // string
typeof (1 + 0)  // number

-대신 사용할 때 문자열 연결이 가능하므로 숫자로 변환합니다.

typeof ("" - 1 + 0) // number

참고 URL : https://stackoverflow.com/questions/24383788/why-does-javascript-handle-the-plus-and-minus-operators-between-strings-and-numb

반응형