J'essaie de filtrer tous les éléments non numériques d'un tableau. Nous pouvons voir la sortie souhaitée lorsque vous utilisez typeof. Mais avec Number, il filtre à zéro.
Voici l'exemple (testé dans Chrome Console):
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number)
// Which output with zero filtered out:
[-1, 1, 2, 3, 4] // 0 is filtered
Si nous utilisons typeof, il ne filtre pas le zéro, comme prévu.
// code
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(n => typeof n === 'number')
// output
[-1, 0, 1, 2, 3, 4, 0]
Ma question:
Quelle est la différence entre les approches "Nombre" et "Typeof"?
Nombre filtres zéro, mais "nombre" lui-même contient littéralement zéro, et cela me perturbe.
Parce que 0
Est l’un des nombreux falsy
valeurs en javascript
Toutes ces conditions seront envoyées à else
blocs:
if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (``)
À partir de la documentation Array.prototype.filter()
:
filter()
appelle une fonctioncallback
fournie une fois pour chaque élément d'un tableau et construit un nouveau tableau de toutes les valeurs pour lesquelles callback renvoie une valeur qui coercite à true
Dans votre cas, la fonction de rappel est le Number
. Donc, votre code est équivalent à:
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(a => Number(a))
// Number(0) -> 0
// Number(Number(0)) -> 0
// Number('') -> 0
// Number('test') -> NaN
Lorsque filter
fonction sélectionne vérité valeurs (ou des valeurs coercitives à true
), les éléments renvoyant 0
Et NaN
sont ignoré. Donc, il retourne [-1, 1, 2, 3, 4]
Pour empêcher le filtrage de falsy zéro, vous pouvez utiliser un autre rappel pour obtenir uniquement des valeurs numériques: Number.isFinite
console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
Ce comportement n'est pas propre à l'utilisation de Number en tant que fonction de filtre. Une fonction de filtrage aussi simple que retourne le 0
value le supprimerait également de la liste.
var a = [-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(v => v)
console.log(a); // [-1, 1, 2, 3, 4, "test"]
Ceci est dû au fait que Number
n'est pas spécifiquement une fonction de filtrage, mais une fonction de transtypage (et un constructeur de classe, mais pas très utile). Alors, quand un nombre (comme 0
) est passé à Number
, il ne fait que renvoyer ce nombre.
Array.prototype.filter
supprime les valeurs qui sont fausseté . En JavaScript, les éléments suivants sont faussés et donc supprimés par filter
.
false
null
undefined
0
NaN
''
""
``
(Pour des raisons complexes de compatibilité descendante MDN va dans , document.all
est aussi une fausseté dans de nombreux navigateurs alors qu’il s’agit d’un objet, mais c’est une note secondaire.)
Zero est une valeur Falsey. Le typeof renvoie toujours une valeur booléenne. Lorsque le nombre 0 est renvoyé, il retourne au test et revient donc à faux. Le nombre zéro est filtré.
C'est parce que 0 est une valeur falsy qui renvoie false et que tout ce qui renvoie false à la fonction de filtrage est filtré du nouveau tableau.
Lorsque vous utilisez Number dans le filtre, en réalité, il passe chaque élément du constructeur Array to Number et, en cas de chaîne ou 0, Number retournera NaN ou 0 et les deux sont faux, le filtre les éliminant.
alors que lorsque vous utilisez typeof, 0 a le type "number", donc il renvoie true et la méthode de filtrage ne le filtre pas