Dlaczego JavaScript inaczej obsługuje operatory plus i minus między ciągami i liczbami?

Nie rozumiem, dlaczego JavaScript działa w ten sposób.

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

Pierwsza linia wyświetla 11, a druga 0. Dlaczego JavaScript obsługuje pierwszy jako ciąg znaków, a drugi jako liczbę?

Author: Community, 2014-06-24

7 answers

String concatenation odbywa się za pomocą +, więc Javascript skonwertuje pierwszą liczbę 1 na łańcuch i połączy "1" i "1" tworząc "11".

Nie można wykonywać odejmowania na ciągach znaków, więc Javascript konwertuje drugą " 1 " na liczbę i odejmuje 1 od 1, co daje zero.

 108
Author: Bernhard Hofmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 10:07:22

+ jest niejednoznaczne. Może oznaczać "konkatenat" lub "Dodaj". Ponieważ jedna strona jest ciągiem, przyjmuje się, że oznacza "konkatenat", stąd wynik to 11 (co, nawiasem mówiąc, było jednym z moich ulubionych żartów jako małe dziecko. Że i "1 + 1 = okno", jak pokazano wizualnie: │┼│ ニ ⊞)

- ma jednak tylko jedno znaczenie: odjąć. Więc to odejmuje.

Tego rodzaju problem nie występuje w innych językach, takich jak PHP, gdzie "concatenate" to . zamiast +, co sprawia, że nie dwuznaczność. Nadal inne języki, takie jak MySQL, nie mają nawet operatora konkatenacji, zamiast tego używają CONCAT(a,b,c...).

 33
Author: Niet the Dark Absol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 10:12:47

Ponieważ spec wyraźnie mówi, aby to zrobić. Strona 75. Zwróć uwagę na różnicę między 11.6.1 kroki 5-8 i 11.6.2 kroki 5-7.

11.6.1 - opisuje jak działa operator dodawania

1-4. ...

5. Niech lprim będzie ToPrimitive (lval).

6. Niech rprim będzie ToPrimitive (rval).

7. Jeśli Type (lprim) jest String lub Type (rprim) jest String, wtedy

7a. Zwraca łańcuch będący wynikiem połączenie ToString(lprim), a następnie ToString (rprim)

8. Zwraca wynik zastosowania operacji dodawania do ToNumber(lprim) i ToNumber (rprim)

11.6.2 - opisuje jak działa operator odejmowania

1-4. ...

5. Niech lnum będzie ToNumber (lval).

6. Niech Rnum będzie ToNumber(Rval).

7. Zwraca wynik zastosowania operacji odejmowania do lnum i rnum

Podsumowanie W przypadku dodawania, jeśli którykolwiek z operandów po przekonwertowaniu na wartość pierwotną bez żadnych podpowiedzi nagle staje się łańcuchem, drugi jest również konwertowany na łańcuch. W przypadku odejmowania oba operandy są konwertowane na liczbę.

 23
Author: Yury Tarabanko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 11:46:50

+ jest operatorem dodawania dla zmiennych numerycznych oraz operatorem konkatenacji dla ciągów znaków.

Za każdym razem, gdy po + występuje ciąg znaków, Javascript zdecyduje się użyć + jako operatora konkatenacji i skonwertuje (wpisuje) jak najwięcej terminów wokół ciągu znaków, aby mógł je połączyć. To tylko zachowanie Javascript. (Jeśli spróbujesz console.log(23 + 2 + "." + 1 + 5 + "02" + 02);, otrzymasz wynik 25.15022. Liczba 02 została wpisana do ciągu 2 przed konkatenowany.

- może być tylko operatorem odejmowania, więc gdy dany ciąg znaków, domyślnie zmieni Typ łańcucha "1" na liczbowy 1; jeśli tego nie zrobił, to "1" - 1 nie miałoby sensu. Jeśli spróbujesz console.log(23 + 2 + 1 + 5 - "02" + 03); otrzymasz 32-ciąg 02 zostanie zamieniony na liczbę 2. Termin po - musi być w stanie przekształcić się w liczbę; jeśli spróbujesz console.log(23 - 2 - "." - 1 - 5 - 02 - "02");, otrzymasz NaN zwrócony.

Co ważniejsze, jeśli spróbujesz console.log(23 + 2 + "." + 1 + 5 - "02" + 03);, wyświetli 26.15, gdzie wszystko przed - było traktowane jako łańcuch znaków (ponieważ zawiera łańcuch znaków ".", a następnie termin po - jest traktowany jako liczba.

 8
Author: dayuloli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-24 15:32:09

Nie ma dedykowanego operatora konkatenacji w JavaScript**. Operator dodawania + wykonuje konkatenację lub dodawanie, w zależności od typu operandów:

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

Nie ma przeciwieństwa konkatenacji (chyba) i operator odejmowania- wykonuje tylko odejmowanie niezależnie od typu operandów:

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

** operator . w PHP i operator & w VB są dedykowanymi operatorami konkatenacji łańcuchów.

 8
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-25 07:22:34

Zgodnie ze standardem EcmaScript 262. Operatory + i - zachowują się inaczej, gdy są zaangażowane łańcuchy. Pierwszy konwertuje każdą wartość na łańcuch znaków. Drugi konwertuje każdą wartość na liczbę.

Od standardu:

Jeśli Type (lprim) is String lub Type (rprim) is String, to zwraca Łańcuch będący wynikiem połączenia ToString (lprim), po którym następuje ToString (rprim)

Zasada ta zakłada, że jeśli w wyrażeniu istnieje wartość łańcuchowa, wszystkie wartości związane z operacją + są konwertowane na łańcuch. W JavaScript, gdy operator + jest używany z łańcuchami, łączy je. Dlatego console.log("5"+1) zwraca "51". 1 jest konwertowane na łańcuch znaków, a następnie" 5 " + " 1 " są łączone razem.

Jednakże powyższa zasada nie dotyczy operatora -. Gdy używasz - wszystkie wartości są konwertowane na liczby zgodnie ze standardem(patrz poniżej). Dlatego w tym przypadku, "5" jest konwertowane na 5, a następnie 1 jest odejmowane.

Od standardu:

5 niech lnum będzie ToNumber (lval).

6 Niech Rnum będzie ToNumber(Rval).


Definicja operatora ze standardowego EcmaScript 262.

Operator + : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 Operator + definicja

Operator - : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2 Operator-definicja

 3
Author: Giuseppe Pes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-27 11:55:41

Używając plus i Ciągu "" w zasadzie zwracasz łańcuch, ponieważ wykonujesz konkatenację:

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

Podczas używania - zamiast tego konwertujesz na liczbę, ponieważ możliwe jest łączenie łańcuchów:

typeof ("" - 1 + 0) // number
 0
Author: GibboK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-26 12:56:03