标准答案
- filter 返回新数组,只包含通过条件的元素。
- callback 返回真值时保留当前元素,返回假值时跳过。
- 结果数组通常是连续数组,不保留未通过元素的原索引空位。
- 稀疏数组不存在的索引不会执行 callback。
- 需要校验 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 会保留原数组长度。
- 遍历稀疏数组时不判断索引是否存在,错误访问空位。