标准答案

  1. filter 返回新数组,只包含通过条件的元素。
  2. callback 返回真值时保留当前元素,返回假值时跳过。
  3. 结果数组通常是连续数组,不保留未通过元素的原索引空位。
  4. 稀疏数组不存在的索引不会执行 callback。
  5. 需要校验 callback 是函数,并支持 thisArg。

题目解析

filter 和 map 的区别在结果长度。map 会保留原长度,filter 只保留符合条件的元素,所以结果通常是紧凑的。

实现时要注意 callback 的判断用真值语义,不要求必须返回 true。返回对象、非空字符串、非零数字都应该视为通过。

它不会修改原数组。如果回调内部修改了原数组,那是回调副作用,不是 filter 自身的行为。

代码示例

filter 的核心是按条件收集通过的元素。

JavaScript
function filter(array, callback, thisArg) {
  if (array == null) {
    throw new TypeError('array is null or undefined')
  }

  if (typeof callback !== 'function') {
    throw new TypeError('callback must be a function')
  }

  const source = Object(array)
  const length = source.length >>> 0
  const result = []

  for (let index = 0; index < length; index += 1) {
    if (index in source && callback.call(thisArg, source[index], index, source)) {
      result.push(source[index])
    }
  }

  return result
}

常见误区

  • 把 callback 返回值和 true 做严格比较,导致返回真值的场景被误过滤。
  • 误以为 filter 会保留原数组长度。
  • 遍历稀疏数组时不判断索引是否存在,错误访问空位。

作者信息