es-toolkit/compat 的 method:预创建按路径调用对象方法的函数
2026/9/16 19:31:44 网站建设 项目流程

es-toolkit/compat 的 method:预创建按路径调用对象方法的函数

【免费下载链接】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

method是 es-toolkit 兼容层(es-toolkit/compat)中与 Lodash 完全对齐的工具函数,它接收一个属性路径和若干预设参数,返回一个"等待对象"的高阶函数:把这个返回函数传给任意对象,就会在指定路径上以正确的this绑定调用该对象上的方法,并把预设参数原样传入。读完本文,你能掌握method的参数与返回值语义、它在函数式编程和Array.map等场景中的典型用法,以及从源码层面理解其路径解析、this绑定与空值处理的完整实现链路。

什么是 method:方法调用的柯里化封装

在函数式编程中,经常需要"先固定调用方式,后传入接收者"。比如要对一组对象逐个调用obj.calc.sum(5, 3),直接写匿名函数略显啰嗦。method将「路径 + 参数」部分应用(partial application)掉,剩下的object参数延迟到调用时才提供:

const methodFunc = method(path, ...args);

这与 Lodash 的_.method行为一致,是 es-toolkit/compat 兼容层 的一部分——该层 1:1 镜像 Lodash 的接口与行为,自 v1.39.3 起通过 Lodash 官方测试套件,因此从lodash迁移过来时调用点无需改动。

基本用法与参数说明

函数签名为method(path, ...args)

  • pathPropertyKey | PropertyKey[]):要调用的方法的路径。可以是点分字符串('a.b')、键数组(['a', 'b'])、数字索引或 symbol;
  • ...argsany[]):调用方法时传入的参数,在创建函数时一次性固定;
  • 返回值:一个(object: any) => any函数,调用时接收目标对象,在其path路径处取出方法并连同args一起执行。
import { method } from 'es-toolkit/compat'; const object = { a: { b: function (x, y) { return x + y; }, }, }; // 创建一个方法调用函数 const add = method('a.b', 1, 2); console.log(add(object)); // => 3 // 对数组中每个对象调用相同路径的方法 const objects = [{ calc: { sum: (a, b) => a + b } }, { calc: { sum: (a, b) => a * b } }]; const calculate = method('calc.sum', 5, 3); objects.map(calculate); // => [8, 15]

第二个例子展示了它的核心优势:method('calc.sum', 5, 3)生成一个可复用的一等函数,直接交给map,避免为每个元素重复书写调用逻辑。

嵌套路径与 this 绑定

method同样支持嵌套路径。值得注意的一点是:被测方法内部访问this.name,而调用结果依然是'Mr. John',说明this被正确绑定到了方法所在的父对象,而非全局环境:

import { method } from 'es-toolkit/compat'; const obj = { users: { getName: function (prefix) { return prefix + this.name; }, name: 'John', }, }; const getUserName = method('users.getName', 'Mr. '); getUserName(obj); // => 'Mr. John'

这一点在测试中也有专门验证:method.spec.ts 中 "should invoke deep property methods with the correctthisbinding" 用例断言{ a: { b() { return this.c; }, c: 1 } }method('a.b')的调用结果为1

源码实现:method 只是 invoke 的柯里化外壳

method.ts 的实现极为简洁——它本身不解析路径,只是把参数固化进闭包,把真正的路径解析与调用交给invoke

export function method(path: PropertyKey | readonly PropertyKey[], ...args: any[]): (object: any) => any { return function (object?: unknown) { return invoke(object, path, args); }; }

真正的工作量在 invoke.ts 中。整个调用链可以概括为:

  1. 参数展平invoke入口先执行args = args.flat(1),以兼容"传一个数组当参数列表"的 Lodash 习惯写法;

  2. 空值守卫object == null时直接返回undefined,不会抛出异常;

  3. 路径分流(invoke.ts):

    • path为字符串时,先检查对象是否直接拥有该字符串键(Object.hasOwn)。若有,则按单一键处理;否则交给 toPath 解析点分/方括号深路径('a.b'['a', 'b']'a["b.c"]'['a', 'b.c']);
    • path为数字或 symbol 时作为单段键直接使用;
    • path为数组时逐段使用,其他类型则包装成单段。

    这个"直接键优先于路径"的策略有对应测试:"should use a key over a path" 用例中,对象同时含有'a.b'键和a.b嵌套,method('a.b')命中的是扁平键。

  4. 父对象定位与方法执行(invokeImpl):用get(object, path.slice(0, -1), object)取到方法的父对象(路径缺失时得到undefined,整体返回undefined),再把最后一段键取出方法并执行func?.apply(parent, args)——apply的第二参数parent正是this绑定正确的来源。

另外从测试可以看到,path支持隐式类型强制:"should coercepathto a string" 用例中,nullundefined、自定义toString的函数、普通对象分别被强制为'null''undefined''fn''[object Object]'后作为键使用;继承属性(原型链上的方法)同样可以被调用,这与 Lodash 行为一致。

边界行为一览(均有测试佐证)

以下行为均可在 method.spec.ts 中找到对应断言,迁移 Lodash 代码时可以放心依赖:

场景行为依据用例
深路径('a.b'/['a','b']正常调用,字符串与数组路径等价"should work with deep property values"
数字路径(如method(array, 1)视为数组索引键"should work with a non-stringpath"
原型链上的方法可被调用(含继承查找)"should work with inherited property values"
对象为null/undefined/ 未传返回undefined,不抛错"should returnundefinedwhenobjectis nullish"
路径中间段缺失返回undefined"should returnundefinedif parts ofpathare missing"
部分应用参数创建时的...args原样传给方法"should apply partial arguments to function"

与 methodOf 的对比:谁在前,谁在后

method与 methodOf 共享同一个invoke内核,只是柯里化的方向相反:

  • method(path, ...args)→ 返回函数接收object:适合"对一组不同对象调用同一方法"(本文开头的map场景);
  • methodOf(object, ...args)→ 返回函数接收path:适合"对同一个对象按不同路径调用方法"。

选择哪个取决于变化量在哪一侧:接收者集合固定时用methodOf,路径与参数固定时用method

引入方式与迁移建议

method位于 compat 子包,标准引入方式:

import { method } from 'es-toolkit/compat';

在无 tree-shaking 环境(CommonJSrequire()、React Native、无打包器的 Node.js 脚本)中,也可以按需引入单函数入口,只加载该函数依赖的文件:

import method from 'es-toolkit/compat/method'; // 或 const method = require('es-toolkit/compat/method');

对于正在从 Lodash 迁移的项目,推荐路径是先整体替换导入为es-toolkit/compat保持调用点不动,再逐步整理为严格的es-toolkitAPI;对于新项目且本就不依赖 Lodash,则可直接使用es-toolkit主包。method这类高阶函数在两种包中的位置不同(compat 面向迁移对齐),选型时留意这一点即可。

本文参考的文档与代码:method 兼容文档、method 实现、invoke 实现、methodOf 实现、toPath 实现、method 测试、compat 包说明。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询