0
votes

Pourquoi [null, undefined, []] == "," renvoie vrai

Je sais que la comparaison abstraite convertira LHS en chaîne et String ([null, undefined, []]) aboutira à ',' .

Mais String (null) est 'null' et String (undefined) est 'undefined' . Alors, comment String ([null, undefined, []]) est ',' ?


2 commentaires

J'aime la question mais pouvez-vous la formater un peu? C'est difficile à lire.


De plus, le titre et le corps du message semblent poser des questions différentes. Les chaînes non vides sont véridiques, les objets tableau sont véridiques, et les tableaux se stringifient simplement différemment de undefined ou null donc je ne trouve pas le comportement surprenant.


3 Réponses :


6
votes

C'est parce que.

  1. C'est ainsi que == est défini https: // tc39.es/ecma262/#sec-abstract-equality-comparison Voir l'étape 11: Si Type (x) est Object et Type (y) est soit String, Number, BigInt ou Symbol, renvoie le résultat de la comparaison? ToPrimitive (x) == y.
  2. Ensuite, ToPrimitive se produit: https://tc39.es/ecma262/ # sec-toprimitive
  3. Ensuite, OrdinaryToPrimitive se produit: https://tc39.es/ecma262/ # sec-ordinairetoprimitive qui appelle Array.prototype.toString
  4. Pour les tableaux, il appelle Array.prototype.join (arr) Voir https://tc39.es/ecma262/#sec-array.prototype.tostring
  5. C'est ainsi que Array.prototype.join est implémenté: https://tc39.es/ecma262/#sec-array.prototype.join , les étapes les plus importantes:
Repeat, while k < len,

* If k > 0, set R to the string-concatenation of R and sep.
* Let element be ? Get(O, ! ToString(k)).
* If element is undefined or null, let next be the empty String; otherwise, let next be ? ToString(element).
* Set R to the string-concatenation of R and next.
* Set k to k + 1.


0 commentaires

2
votes

La réponse de zerkms est excellente si vous voulez les spécifications détaillées. Dans un langage plus simple, c'est comme ça:

  1. Le constructeur String convertit essentiellement le paramètre que vous passez en chaîne.
  2. Dans ce cas, le paramètre est un tableau (créé via la syntaxe [...] ).
  3. La conversion d'un tableau en chaîne se fait en créant une liste séparée par des virgules des représentations sous forme de chaîne des valeurs qu'il contient, avec une mise en garde intéressante: même si undefined et null code > serait normalement converti en "undefined" et "null" , la spécification pour Array.prototype.join référencée dans la réponse de zerkms spécifie qu'il utilisera une chaîne vide au lieu de faire une conversion de chaîne normale.
  4. Le troisième élément de votre tableau est un tableau vide (à nouveau créé via la syntaxe [] ). Comme il n'y a rien à séparer par des virgules, cela produit également une chaîne vide lors de la conversion en chaîne.

Vous vous retrouvez donc avec une chaîne vide suivie d'une virgule, suivie d'une autre chaîne vide, suivie d'une virgule, suivie d'une autre chaîne vide. Par conséquent, ",".

Une autre façon de voir les choses est que vous appelez essentiellement:

[undefined, null, []].join(",")

... qui traite les valeurs indéfinies et null comme s'il s'agissait de chaînes vides.


5 commentaires

Oui, c'est une reformulation des spécifications, mes excuses, j'ai supprimé mon autre commentaire


@zerkms: Ah, en effet, vous avez raison. Je vais réparer ça ...


Ce que je veux dire, c'est qu'il est difficile de le dire à la fois «compréhensible» et «pas trop mal» simultanément :-)


Je comprends totalement ce que tu veux dire. J'espère que ma reformulation est moins fausse et toujours compréhensible.


Ouais, maintenant c'est beaucoup mieux, désolé encore pour le pinaillage



1
votes

Je sais que la comparaison abstraite convertira LHS en String et La chaîne ([null, undefined, []]) se traduira par «,».

Mais String (null) est "null" et String (undefined) est "undefined". Alors comment String ([null, undefined, []]) vaut ","?

Pourquoi pensez-vous que func ([x, y, z]) devrait être égal à func (x) + func (y) + func (z) ?

Voir ces exemples:

String([1, 2]); // "1,2"
String([null]); // ""
String([undefined]); // ""
String([[]]); // ""
String([1, null, undefined]); // "1,,"

// In same way 

String([null, undefined, []]); // ",,"

Essayez de relier ces exemples à votre question.


0 commentaires