web-dev-qa-db-fra.com

Pourquoi JavaScript gère-t-il différemment les opérateurs plus et moins entre les chaînes et les nombres?

Je ne comprends pas pourquoi JavaScript fonctionne de cette façon.

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

La première ligne affiche 11 et la seconde 0. Pourquoi JavaScript traite-t-il le premier comme une chaîne et le second comme un nombre?

61
Nir

La concaténation des chaînes se fait avec + afin que Javascript convertisse le premier 1 numérique en une chaîne et concatène "1" et "1" en "11".

Vous ne pouvez pas effectuer de soustraction sur les chaînes, donc Javascript convertit le deuxième "1" en nombre et soustrait 1 de 1, ce qui donne zéro.

93
Bernhard Hofmann

+ Est ambigu. Cela peut signifier "concaténer" o "ajouter". Puisqu'un côté est une chaîne, cela signifie "concaténer", d'où le résultat est 11 (qui, soit dit en passant, était l'une de mes blagues préférées quand j'étais jeune. Cela et "1 + 1 = fenêtre", comme affiché visuellement: │┼│ ニ ⊞)

- N'a cependant qu'une seule signification: soustraire. Il soustrait donc.

Ce type de problème n'est pas présent dans d'autres langages tels que PHP, où "concaténer" est . Au lieu de +, Ce qui ne fait aucune ambiguïté. D'autres langages comme MySQL n'ont même pas d'opérateur de concaténation, utilisant plutôt CONCAT(a,b,c...).

33

Parce que la spécification dit explicitement de le faire. Page 75. Notez la différence entre 11.6.1 étapes 5-8 et 11.6.2 étapes 5-7.

11.6.1 - décrit le fonctionnement de l'opérateur d'addition

1-4. ...

5. Soit lprim ToPrimitive (lval).

6. Soit rprim soit ToPrimitive (rval).

7. Si Type (lprim) est String ou Type (rprim) est String, alors

7a. Renvoie la chaîne résultant de la concaténation de ToString (lprim) suivi de ToString (rprim)

8. Renvoie le résultat de l'application de l'opération d'ajout à ToNumber (lprim) et ToNumber (rprim)

11.6.2 - décrit le fonctionnement de l'opérateur de soustraction

1-4. ...

5. Soit lnum ToNumber (lval).

6. Soit rnum ToNumber (rval).

7. Renvoie le résultat de l'application de l'opération de soustraction à lnum et rnum

Résumé En cas d'ajout si l'un des opérandes convertis en valeur primitive sans aucune indication devient soudainement une chaîne, le second est également converti en chaîne. En cas de soustraction, les deux opérandes sont convertis en un nombre.

22
Yury Tarabanko

+ Est à la fois un opérateur d'addition pour les variables numériques et un opérateur de concaténation pour les chaînes.

Chaque fois qu'il y a une chaîne après un +, Javascript choisira d'utiliser le + Comme opérateur de concaténation et convertira (tapera) autant de termes que possible autour de la chaîne afin de pouvoir les concaténer. C'est juste le comportement de Javascript. (Si vous avez essayé console.log(23 + 2 + "." + 1 + 5 + "02" + 02);, vous obtiendrez le résultat 25.15022. Le nombre 02 A été tapé dans la chaîne 2 Avant d'être concaténé.

- Ne peut être qu'un opérateur de soustraction, donc quand on lui donne une chaîne, il changera implicitement le type de la chaîne "1" En un 1 Numérique ; s'il ne faisait pas cela, il n'y avait aucun moyen que "1" - 1 ait du sens. Si vous avez essayé console.log(23 + 2 + 1 + 5 - "02" + 03); vous obtiendrez 32 - la chaîne 02 Est convertie en nombre 2. Le terme après le - Doit pouvoir être converti en nombre; si vous avez essayé console.log(23 - 2 - "." - 1 - 5 - 02 - "02"); vous obtiendrez NaN retourné.

Plus important encore, si vous avez essayé console.log(23 + 2 + "." + 1 + 5 - "02" + 03);, il affichera 26.15, Où tout ce qui se trouvait avant - A été traité comme une chaîne (car il contient une chaîne "." , puis le terme après le - est traité comme un nombre.

7
dayuloli

Il n'y a pas d'opérateur de concaténation de chaînes dédié en JavaScript **. L'opérateur d'addition + effectue une concaténation ou une addition de chaînes, selon le type d'opérandes:

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

Il n'y a pas d'opposé de la concaténation (je pense) et de l'opérateur de soustraction - effectue uniquement la soustraction quel que soit le type d'opérandes:

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

** Le . opérateur dans PHP et & opérateur dans VB sont des opérateurs de concaténation de chaînes dédiés.

6
Salman A

Selon le standard EcmaScript 262. Les opérateurs + Et - Se comportent différemment lorsque des chaînes sont impliquées. Le premier convertit chaque valeur en chaîne. Le second convertit chaque valeur en nombre.

De la norme:

Si Type (lprim) est String ou Type (rprim) est String, retournez la chaîne résultant de la concaténation de ToString (lprim) suivie de ToString (rprim)

Ces règles impliquent que si dans l'expression il y a une valeur de chaîne, toutes les valeurs impliquées dans l'opération + Sont converties en chaîne. En JavaScript, lorsque l'opérateur + Est utilisé avec des chaînes, il les concatène. C'est pourquoi console.log("5"+1) renvoie "51". 1 Est converti en chaîne, puis "5" + "1" sont concaténés ensemble.

Néanmoins, la règle ci-dessus ne s'applique pas à l'opérateur -. Lorsque vous utilisez un - Toutes les valeurs sont converties en nombres conformément à la norme (voir ci-dessous). Par conséquent, dans ce cas, "5" Est converti en 5 Puis 1 Est soustrait.

De la norme:

5 Soit lnum ToNumber (lval).

6 Soit rnum ToNumber (rval).


Définition d'opérateur à partir du standard EcmaScript 262.

Opérateur + : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 Operator + definition

Opérateur - : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2 Operator - definition

3
Giuseppe Pes

Utilisation de plus et d'une chaîne "" vous renvoyez essentiellement une chaîne car vous effectuez une concaténation:

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

Lors de l'utilisation de - à la place, vous convertissez en nombre car la concaténation de chaînes est possible:

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