Lodash源码阅读-without

Lodash 源码阅读-without

概述

without 函数用于创建一个新数组,其中排除了所有给定的值。它使用 SameValueZero 算法进行相等性比较,这意味着它可以正确处理 NaN 等特殊值。与 _.pull 不同,without 不会修改原数组,而是返回一个新数组。

前置学习

依赖函数

  • baseRest:用于处理不定参数,类似 ES6 的剩余参数功能
  • isArrayLikeObject:检查值是否为类数组对象
  • baseDifference:计算数组差集的基础实现

技术知识

  • SameValueZero :ECMAScript 规范中的比较算法,与 === 类似但能正确处理 NaN
  • 不定参数处理:处理可变数量的函数参数
  • 数组差集:从一个数组中移除另一个数组中存在的元素

源码实现

js 复制代码
var without = baseRest(function (array, values) {
  return isArrayLikeObject(array) ? baseDifference(array, values) : [];
});

实现思路

without 函数的实现非常简洁,主要分为三个步骤:

  1. 使用 baseRest 包装函数,处理不定参数,将第一个参数识别为 array,其余参数收集到 values 数组中
  2. 检查 array 是否为类数组对象,确保输入有效
  3. 如果输入有效,调用 baseDifference 计算差集;否则返回空数组

这种实现方式既简洁又高效,可以处理各种输入情况,同时保持了函数的健壮性。

源码解析

函数签名和参数处理

js 复制代码
var without = baseRest(function(array, values) {

without 使用 baseRest 高阶函数进行包装,这使它能够接收不定数量的参数:

  • 第一个参数 array 是要处理的数组
  • 剩余的所有参数会被收集到 values 数组中

baseRest 的作用类似于 ES6 的剩余参数 ...values,但它提供了更多的灵活性和兼容性。

类型检查和结果计算

js 复制代码
return isArrayLikeObject(array) ? baseDifference(array, values) : [];

这部分代码执行两个关键操作:

  1. 类型检查 :使用 isArrayLikeObject 判断 array 是否为类数组对象

    • 类数组对象包括数组、arguments 对象、DOM 集合等
    • 这个检查确保了函数能安全处理各种输入
  2. 差集计算

    • 如果 array 是类数组对象,调用 baseDifference(array, values) 计算差集
    • 如果 array 不是类数组对象,直接返回空数组 [],避免程序异常

baseDifference 的工作原理

baseDifference 是 Lodash 内部的一个函数,用于计算数组差集。它的工作流程如下:

  1. 初始化结果数组 result = []
  2. 如果源数组为空,直接返回空结果
  3. 如果有 iterateecomparator,使用相应的方式处理比较逻辑
  4. 对于大型数组,使用 SetCache 优化比较性能
  5. 遍历源数组中的每个元素:
    • 如果元素不在排除值列表中,将其添加到结果数组
    • 使用严格相等比较(SameValueZero)或自定义比较器进行比较

使用示例

基本使用

js 复制代码
_.without([2, 1, 2, 3], 1, 2);
// => [3]

在这个例子中:

  • 源数组是 [2, 1, 2, 3]
  • 要排除的值是 12
  • 结果是 [3],即源数组中所有非 12 的元素

对象数组比较

js 复制代码
var object1 = { a: 1 };
var object2 = { b: 2 };
var array = [object1, object2];

_.without(array, { a: 1 });
// => [object1, object2],因为使用严格相等比较

_.without(array, object1);
// => [object2],成功移除了 object1

这个例子展示了 without 使用严格相等比较的特性:

  • 即使 { 'a': 1 }object1 内容相同,但它们是不同的对象引用
  • 只有直接引用 object1 才能成功排除它

总结

without 函数提供了一种简便的方式来创建排除特定值的新数组。其主要特点包括:

  1. 不可变性:不修改原数组,而是返回新数组,符合函数式编程原则
  2. 灵活的参数:支持排除多个值,提高了使用便利性
  3. 严格比较:使用 SameValueZero 算法进行比较,确保准确性
  4. 类型安全:对输入进行类型检查,增强了函数的健壮性

虽然 without 的功能可以通过 filter 实现,但它提供了更简洁的 API,特别适合从数组中快速排除一些已知值的场景。

如果需要更复杂的排除逻辑,可以考虑使用 Lodash 的其他方法:

  • _.difference:排除另一个数组中的所有值
  • _.differenceBy:支持通过迭代器进行值转换后比较
  • _.differenceWith:支持自定义比较器进行比较
相关推荐
J***Q29219 小时前
Vue数据可视化
前端·vue.js·信息可视化
ttod_qzstudio21 小时前
深入理解 Vue 3 的 h 函数:构建动态 UI 的利器
前端·vue.js
芳草萋萋鹦鹉洲哦21 小时前
【elemen/js】阻塞UI线程导致的开关卡顿如何优化
开发语言·javascript·ui
_大龄21 小时前
前端解析excel
前端·excel
1***s63221 小时前
Vue图像处理开发
javascript·vue.js·ecmascript
槁***耿21 小时前
JavaScript在Node.js中的事件发射器
开发语言·javascript·node.js
一叶茶21 小时前
移动端平板打开的三种模式。
前端·javascript
前端大卫21 小时前
一文搞懂 Webpack 分包:async、initial 与 all 的区别【附源码】
前端
U***49831 天前
JavaScript在Node.js中的Strapi
开发语言·javascript·node.js
Want5951 天前
HTML音乐圣诞树
前端·html