web-dev-qa-db-ja.com

Array.filter(Number)がJavaScriptでゼロを除外するのはなぜですか?

配列からすべての非数値要素を除外しようとしています。 typeofを使用すると、目的の出力を確認できます。しかし、Numberを使用すると、ゼロが除外されます。

次に例を示します(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

Typeofを使用する場合、ゼロをフィルタリングしません。

// code
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(n => typeof n === 'number')
// output
[-1, 0, 1, 2, 3, 4, 0]

私の質問:

  1. 「Number」アプローチと「typeof」アプローチの違いは何ですか?

  2. 数字はゼロをフィルタリングしますが、「数字」自体は文字通りゼロを含み、これは私を混乱させます。

41
imckl

0は、javascriptの多くの falsy 値の1つであるため

これらの条件はすべてelseブロックに送信されます。

if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (``)

Array.prototype.filter() ドキュメントから:

filter()は、配列内の各要素に対して提供されたcallback関数を1回呼び出し、コールバックがtrueに強制する値を返すすべての値の新しい配列を構築します

あなたの場合、コールバック関数はNumberです。したがって、あなたのコードは次と同等です:

[-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

filter関数が truthy 値(またはtrueに強制する値)を選択すると、0およびNaNを返す項目は無視されます。したがって、[-1, 1, 2, 3, 4]を返します

36
adiga

falsy ゼロがフィルタリングされないようにするには、別のコールバックを使用して数値のみを取得します。 Number.isFinite

console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
12
Nina Scholz

予想される行動

この動作は、Numberをフィルター関数として使用する場合に固有のものではありません。 0値を単純に返すフィルター関数も、リストから削除します。

var a = [-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(v => v)
console.log(a); // [-1, 1, 2, 3, 4, "test"]

これは、 Number が特にフィルター関数ではなく、主に型キャスト関数(およびクラスコンストラクターですが、あまり有用ではない)であるためです。したがって、数値(0など)がNumberに渡されると、その数値が返されます。

Array.prototype.filterfalsy である値を削除します。 JavaScriptでは、以下は偽物であるため、filterによって削除されます。

false
null
undefined
0
NaN
''
""
``

(複雑な後方互換性の理由のため MDNが入る 、オブジェクトであるにも関わらず、document.allは多くのブラウザでも偽物ですが、それは補足です)

5

ゼロは偽の値です。 typeofは常にブール値を返します。数字の0が返されると、テストに戻っているため、偽として返されるため、数字の0は除外されます。

4
bronkula

0は偽を返す偽の値であり、フィルター関数に偽を返すものはすべて新しい配列から除外されるためです。

ドキュメンテーション

https://developer.mozilla.org/en-US/docs/Glossary/Falsy

3
AnonymousSB

フィルターで数値を使用している場合、実際には配列の各項目を数値コンストラクターに渡し、文字列または0の場合、数値はNaNまたは0を返し、両方ともfalseであるため、フィルターは両方をフィルタリングします

一方、typeofを使用している場合、0は "number"タイプであるため、trueを返し、フィルターメソッドはフィルターアウトしません

3
Abhay Sehgal