我正在尝试从数组中过滤掉所有非数字元素。使用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
如果我们使用typeof,它不会过滤出预期的零。
// code
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(n => typeof n === 'number')
// output
[-1, 0, 1, 2, 3, 4, 0]
我的问题:
“数字”方法和“类型”方法有什么区别?
数字过滤为零,但是“数字”本身实际上包含零,这使我感到困惑。
答案 0 :(得分:34)
因为0
是javascript中许多falsy
值之一
所有这些条件都将发送到else
块:
if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (``)
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
当filter
函数选择truthy个值(或强制转换为true
的值)时,返回0
和NaN
的项目将被忽略。因此,它将返回[-1, 1, 2, 3, 4]
答案 1 :(得分:12)
为防止过滤falsy零,您可以使用另一个回调仅获取数值:Number.isFinite
console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
答案 2 :(得分:5)
使用数字作为过滤器功能并非唯一。简单返回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 goes into,document.all
在许多浏览器中尽管是对象也很虚假,但这只是一个旁注)
答案 3 :(得分:4)
零是一个假值。 typeof始终返回布尔值。返回数字0时,它将返回测试,因此返回为false,因此将数字0过滤掉。
答案 4 :(得分:3)
这是因为0是一个伪造的值,它返回false,并且将向filter函数返回false的所有内容都从新数组中过滤掉。
答案 5 :(得分:3)
在过滤器中使用Number时,实际上是将Array的每个项目传递给Number构造函数,如果是字符串或0,则Number将返回NaN或0,并且两者均为假,因此filter会将它们都过滤掉
而当您使用typeof时,则0为“数字”类型,因此它返回true,并且filter方法不会将其过滤掉
答案 6 :(得分:2)
为防止过滤falsy零,您可以使用另一个回调仅获取数值:Number.isFinite
console.log([-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite))
答案 7 :(得分:0)
此行为的原因是0, null, undefined, NaN
在JavaScript中等于false,因此,在第一种情况下:
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number);
当将Number用作过滤器中的参数之一时,它将返回数字本身。因此,当传递0时,它将返回0,而javascript将其理解为false
。因此,它返回
[-1, 1, 2, 3, 4]
为了安全起见,建议使用Number.isFinite
而不是Number
。
[-1, 0, 1, 2, 3, 4, Number(0), '', 'test'].filter(Number.isFinite);
给出与
相同的结果[-1,0,1,2,3,4, Number(0), '','test'].filter(n=> typeof n === 'number');
会给。
答案 8 :(得分:0)
这是另一个示例,显示了如何从数字数组中删除多个索引并处理0:
const array = [0,1,2,3,4,5,6,7,8,9]
console.log('init', array)
const indicesToDel = [2, 3, 5, 9]
console.log('indices to del', indicesToDel)
let result = array.filter( (item, index) => !indicesToDel.includes(index) ? Number.isFinite(item) : false )
console.log('result', result)