为什么Array.filter(Number)在JavaScript中过滤掉了?

imc*_*ckl 42 javascript numbers typeof

我正在尝试从数组中过滤掉所有非数字元素.使用typeof时,我们可以看到所需的输出.但是使用Number,它会过滤掉零.

以下是示例(在Chrome控制台中测试):

[-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
Run Code Online (Sandbox Code Playgroud)

如果我们使用typeof,它不会过滤零,这是预期的.

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

我的问题:

  1. 'Number'和'typeof'方法有什么区别?

  2. 数字过滤零,但'数字'本身确实包含零,这让我感到困惑.

adi*_*iga 37

因为0falsyjavascript 中的众多值之一

所有这些条件都将被发送到else块:

if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (``)
Run Code Online (Sandbox Code Playgroud)

Array.prototype.filter()文档:

filter()callback为数组中的每个元素调用一次提供的函数,并构造一个包含所有值的新数组,其中回调返回一个强制为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
Run Code Online (Sandbox Code Playgroud)

filter函数选择truthy值(或强制的true)时,返回0NaN忽略的项.所以,它返回[-1, 1, 2, 3, 4]

  • 请注意,`new Boolean(false)`是真实的,以及一个空对象(`{}`)和一个空数组(`[]`). (4认同)

Nin*_*olz 12

为了防止虚假零过滤,您可以使用另一个回调来获取数值:Number.isFinite

console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
Run Code Online (Sandbox Code Playgroud)


Ale*_*ara 5

预期的行为

使用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"]
Run Code Online (Sandbox Code Playgroud)

这是因为Number它不是一个特定的过滤函数,它主要是一个类型转换函数(和一个类构造函数,但不是一个非常有用的函数).因此,当0传递一个数字(如)时Number,它只返回该数字.

Array.prototype.filter删除虚假的值.在JavaScript中,以下是假的,因此被删除filter.

false
null
undefined
0
NaN
''
""
``
Run Code Online (Sandbox Code Playgroud)

(出于复杂的向后兼容性原因,MDN进入,document.all尽管是一个对象,但在许多浏览器中也是假的,但这是一个侧面说明)