配列からすべての非数値要素を除外しようとしています。 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]
私の質問:
「Number」アプローチと「typeof」アプローチの違いは何ですか?
数字はゼロをフィルタリングしますが、「数字」自体は文字通りゼロを含み、これは私を混乱させます。
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]
を返します
falsy ゼロがフィルタリングされないようにするには、別のコールバックを使用して数値のみを取得します。 Number.isFinite
console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
この動作は、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.filter
は falsy である値を削除します。 JavaScriptでは、以下は偽物であるため、filter
によって削除されます。
false
null
undefined
0
NaN
''
""
``
(複雑な後方互換性の理由のため MDNが入る 、オブジェクトであるにも関わらず、document.all
は多くのブラウザでも偽物ですが、それは補足です)
ゼロは偽の値です。 typeofは常にブール値を返します。数字の0が返されると、テストに戻っているため、偽として返されるため、数字の0は除外されます。
0は偽を返す偽の値であり、フィルター関数に偽を返すものはすべて新しい配列から除外されるためです。
フィルターで数値を使用している場合、実際には配列の各項目を数値コンストラクターに渡し、文字列または0の場合、数値はNaNまたは0を返し、両方ともfalseであるため、フィルターは両方をフィルタリングします
一方、typeofを使用している場合、0は "number"タイプであるため、trueを返し、フィルターメソッドはフィルターアウトしません