JavaScript中的find、filter和Boolean转换:巧妙的细节决定输出结果

62 阅读2分钟

先看下面的两段代码,判断一下输出是否相同

代码演示

代码1:

const list = [{id: 1, name: 'test1'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}]
const emptyKey = [2]
const findEmptyItem = list.find((item) => {
  return emptyKey.filter((it) => {
    return item.id === it
  })
})
console.log(findEmptyItem)

代码2:

const list = [{id: 1, name: 'test1'}, {id: 2, name: 'test2'}, {id: 3, name: 'test3'}]
const emptyKey = [2]
const findEmptyItem = list.find((item) => {
  return emptyKey.find((it) => {
    return item.id === it
  })
})
console.log(findEmptyItem)

⏱️思考5分钟......

是不是第一感觉会觉得两者输出一样(反正我是😬🥲),然后发现 大错特错❌

答案是这样的:

上述代码输出结果

代码1 : {id: 1, name: 'test1'}

代码2: {id: 2, name: 'test2'}

我们所期望的结果: {id: 2, name: 'test2'}

再思考5分钟⌛️......, 究竟是哪里出现了问题🤔️😖

5分钟过后(去翻阅下资料💾)......

原来如此!(恍然大悟💡)

问题就出现在:

  1. find在查找的时候:

按索引升序顺序为数组中的每个元素调用提供的 callbackFn 函数,直到 callbackFn 返回一个真值。然后 find() 返回该元素并停止迭代数组。如果 callbackFn 从未返回真值,则 find() 返回 undefined

❗❗它返回的是数组中第一个满足所提供测试函数的元素的值,否则返回 ****undefined

  1. filter在筛选的时候:

它为数组中的每个元素调用提供的 callbackFn 函数一次,并构造一个由所有返回真值的元素值组成的新数组。未通过 callbackFn 测试的数组元素不会包含在新数组中。

❗❗它返回的是给定数组的一部分的浅拷贝,其中只包括通过提供的函数实现的测试的元素。如果没有元素通过测试,则返回一个空数组,也就是 []

  1. Boolean([]) === true, Boolean(undefined) === false

大家看到这里应该就很清楚问题出现在哪了:

filter第一次执行的时候返回的是[], 是真值,所以find就不会再往下判断了,find找到元素中第一个符合条件的就结束了,所以返回的是第一个对象。

最后再补充一点Boolean转换相关的知识点吧

如果布尔对象无初始值或者其值为:

  • 0
  • -0
  • null
  • ""
  • false
  • undefined
  • NaN

那么对象的值为 false。否则,其值为 true(即使当变量值为字符串 "false" 时)!

👏👏结束🔚