Je sais que la comparaison abstraite convertira LHS en chaîne et String ([null, undefined, []])
aboutira à ','
. p >
Mais String (null)
est 'null'
et String (undefined)
est 'undefined'
. Alors, comment String ([null, undefined, []])
est ','
?
3 Réponses :
C'est parce 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.
ToPrimitive
se produit: https://tc39.es/ecma262/ # sec-toprimitive OrdinaryToPrimitive
se produit: https://tc39.es/ecma262/ # sec-ordinairetoprimitive qui appelle Array.prototype.toString
Array.prototype.join (arr)
Voir https://tc39.es/ecma262/#sec-array.prototype.tostring 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.
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:
[...]
). 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.
[]
). 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.
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
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.
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
ounull
donc je ne trouve pas le comportement surprenant.