es-toolkit 入门指南:现代高性能 JavaScript 工具库的核心能力与实战用法
【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit
es-toolkit 是一款面向日常开发的现代化 JavaScript 工具库,通过充分运用最新的 JavaScript API 实现,在 bundle 体积(最大缩小 97%) 与 运行时性能(2~3 倍提升) 两方面相较 lodash 等传统工具库都有显著优势,同时内置完善的 TypeScript 类型并追求 100% 测试覆盖率。本文以 docs/ja/intro.md(es-toolkit 的日语介绍文档)为骨架,结合仓库源码与安装文档 docs/ja/usage.md,系统讲解其设计理念、功能分类、安装方式与核心 API 的源码级实现,帮助你快速上手并正确选用。
为什么选择 es-toolkit:体积与性能的取舍逻辑
es-toolkit 的定位可以概括为三个关键词:现代实现、极致体积、高性能。
- 现代实现:库中大量函数直接基于
Set、AbortSignal、Map等较新的 JavaScript 语言能力实现,而非像 lodash 那样兼容上古运行时的复杂回退逻辑。以去重函数为例,es-toolkit 的 uniq 核心代码仅一行:return [...new Set(arr)]。 - 体积优势:同一函数基准下,es-toolkit 相比 lodash 的 bundle 体积最大可缩小97%,部分工具函数体积甚至不足 100 字节。这得益于零依赖、充分的 tree-shaking 支持(
package.json中声明了"sideEffects": false,package.json)以及按模块拆分导出。 - 性能优势:平均 2 倍、部分函数最高 11 倍的运行时性能提升,具体对比数据与测量方法可参考 docs/ja/performance.md 和 docs/ja/bundle-size.md。
其中体积指标的测量方式如下:使用 esbuild 0.28.0 对如下代码进行打包(完整基准代码位于 benchmarks/bundle-size):
import { chunk } from 'es-toolkit'; // 或者 import { chunk } from 'lodash-es'; console.log(chunk);提供的功能分类
es-toolkit 按使用场景将函数划分为以下分类(各分类均有独立的子路径导出,见 package.json):
| 分类 | 用途 | 代表函数 | 参考文档 |
|---|---|---|---|
| Array | 数组操作 | uniq、difference | src/array |
| Function | 控制函数执行 | debounce、throttle | src/function |
| Math | 数值运算 | sum、round | src/math |
| Object | 对象操作 | pick、omit | src/object |
| Predicate | 类型守卫 | isNotNil | src/predicate |
| Promise | 异步操作 | delay | src/promise |
| String | 字符串操作 | snakeCase | src/string |
除上述分类外,仓库中还包含
bigint、map、set、iterator、error、server、types、util等模块(src/index.ts 的导出声明),全部模块均可通过es-toolkit/<模块名>的方式按需导入。
安装与使用
Node.js(npm / pnpm / yarn)
es-toolkit 支持 Node.js 18 及以上版本,使用你习惯的包管理器即可安装:
npm install es-toolkitpnpm add es-toolkityarn add es-toolkit安装后直接按命名导入使用:
import { sum } from 'es-toolkit'; sum([1, 2, 3]);Deno(通过 JSR)
Deno 环境通过 JSR 安装,由于 JSR 的命名空间限制,导入路径需要额外的@es-toolkit作用域:
deno add jsr:@es-toolkit/es-toolkitimport { sum } from '@es-toolkit/es-toolkit'; sum([1, 2, 3]);Bun
bun add es-toolkit浏览器(CDN)
与 lodash 类似,es-toolkit 的全局构建会将所有函数挂载到_变量上(package.json中jsdelivr/unpkg字段指向 dist/browser.global.js):
<!-- jsdelivr --> <script src="https://cdn.jsdelivr.net/npm/es-toolkit@%5E1"></script> <script> var arr = _.chunk([1, 2, 3, 4, 5, 6], 3); </script><!-- unpkg --> <script src="https://unpkg.com/es-toolkit@%5E1"></script> <script> var arr = _.chunk([1, 2, 3, 4, 5, 6], 3); </script>现代浏览器还可以配合 import map 使用 ESM 版本:
<script type="importmap"> { "imports": { "es-toolkit": "https://esm.sh/es-toolkit@%5E1" } } </script> <script type="module"> import { chunk } from 'es-toolkit'; chunk([1, 2, 3, 4, 5, 6], 3); </script>核心 API 源码解析
Array:基于 Set 的现代实现
uniq 使用Set天然的去重语义,一行代码即完成去重并保持首次出现顺序:
export function uniq<T>(arr: readonly T[]): T[] { return [...new Set(arr)]; }difference 先将第二个数组转成Set再做过滤,将判断复杂度从 O(n×m) 降为 O(n+m):
export function difference<T>(firstArr: readonly T[], secondArr: readonly T[]): T[] { const secondSet = new Set(secondArr); return firstArr.filter(item => !secondSet.has(item)); }这种“Set 化 + 线性过滤”的模式在仓库中广泛复用(如 intersection、union 等),是体积小、性能高的关键原因之一。
Function:带 AbortSignal 的 debounce
debounce 除了标准的延迟执行语义外,还提供了三个值得关注的特性:
- 返回的函数带有
cancel()、flush()、schedule()三个方法,分别用于取消待执行调用、立即执行挂起调用、重新调度定时器; - 支持
edges选项,可指定在延迟窗口的leading(开头)、trailing(结尾)或两者都触发执行,默认值为["trailing"]; - 支持
signal(AbortSignal)选项,当信号中止时自动取消挂起的调用(内部通过signal.addEventListener('abort', cancel, { once: true })注册监听),便于与 AbortController 集成做取消控制。
典型用法:
const debouncedFunction = debounce(() => { console.log('Function executed'); }, 1000); debouncedFunction(); // 1 秒内无再次调用则执行 debouncedFunction.cancel(); // 取消待执行调用 // 结合 AbortSignal const controller = new AbortController(); const debouncedWithSignal = debounce( () => console.log('Function executed'), 1000, { signal: controller.signal } ); debouncedWithSignal(); controller.abort(); // 取消该次 debouncePromise:可取消的 delay
delay 返回一个在指定毫秒后 resolve 的 Promise,可在 async/await 中直接使用;传入signal后,中止信号会以AbortError拒绝该 Promise:
import { delay } from 'es-toolkit'; async function foo() { console.log('Start'); await delay(1000); // 延迟 1 秒 console.log('End'); } const controller = new AbortController(); const { signal } = controller; setTimeout(() => controller.abort(), 50); try { await delay(100, { signal }); } catch (error) { console.error(error); // AbortError }Predicate:类型守卫 isNotNil
isNotNil 是带 TypeScript 类型谓词签名(x is T)的函数,可直接用于filter等场景,让编译器自动收窄类型:
// arr 的类型是 (number | undefined)[] const arr = [1, undefined, 3]; // result 的类型被收窄为 number[] const result = arr.filter(isNotNil); // result 为 [1, 3]String:snakeCase
snakeCase 先借助内部words函数将字符串切分为单词序列,再统一转小写并用下划线连接:
snakeCase('camelCase'); // 'camel_case' snakeCase('some whitespace'); // 'some_whitespace' snakeCase('hyphen-text'); // 'hyphen_text' snakeCase('HTTPRequest'); // 'http_request'类型安全与可靠性保障
- 内置 TypeScript 类型:所有函数均附带完整泛型签名与类型谓词,开发者无需额外安装
@types包,且 jsr.json 等发布配置同时面向 npm 与 JSR 双生态; - 100% 测试覆盖率:每个函数都配有同名
.spec.ts测试文件(如 src/array/uniq.spec.ts、src/function/debounce.spec.ts),仓库通过 Vitest 运行测试(yarn test,见 package.json),并以 100% 覆盖率为目标保障可靠性。
进一步学习
- 各分类的完整函数参考:见 docs/ja/reference(另有英语 docs/reference、简体中文 docs/zh_hans/reference 等多语言版本);
- 体积与性能的量化对比:docs/ja/bundle-size.md、docs/ja/performance.md;
- lodash 兼容层(compat)与函数式编程(fp)模块:docs/ja/compat/intro.md、docs/ja/fp/intro.md。
结语
es-toolkit 以现代 JavaScript 能力为基石,在保持 API 简洁易用的同时实现了体积与性能的双重突破,并以完善的类型系统与测试覆盖保证了生产可用的可靠性。无论是替换既有项目中的 lodash 依赖,还是在 Node.js、Deno、Bun 或浏览器中从零构建应用,它都值得作为首选的工具库纳入技术选型。若需在本地查看源码与运行测试,可在仓库根目录执行yarn install后通过yarn test运行测试、yarn bench运行基准测试(见 package.json)。
【免费下载链接】es-toolkitA modern JavaScript utility library that's 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考