尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

es-toolkit isFunction 完全指南:JavaScript 函数类型检测的原理与实战

es-toolkit isFunction 完全指南:JavaScript 函数类型检测的原理与实战 es-toolkit isFunction 完全指南JavaScript 函数类型检测的原理与实战【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkitisFunction是 es-toolkit 在predicate分类下提供的一个类型检测工具函数用于判断给定值是否为函数。它覆盖普通函数、异步函数、生成器函数、构造函数以及各类 JavaScript 内置函数与类在回调函数验证、动态函数调用等场景中扮演基础而关键的角色。阅读本文后你将掌握isFunction的完整用法、TypeScript 类型收窄机制以及它在 es-toolkit 内部被其他工具函数复用的底层原理。函数签名与核心实现isFunction的调用形式非常简单const result isFunction(value);其完整源码位于 src/predicate/isFunction.ts整个实现只有一行却蕴含着 TypeScript 类型收窄的关键设计export function isFunction(value: any): value is (...args: any[]) any { return typeof value function; }从源码可以提炼出三个核心事实判定依据是typeof运算符JavaScript 中typeof对函数类型值返回字符串function这是语言层面的内置检测机制任何函数无论普通、异步、生成器还是构造函数都会被命中返回类型是类型谓词type predicate返回值声明为value is (...args: any[]) any意味着在 TypeScript 中一旦isFunction(value)返回true编译器就会把value的类型自动收窄为可调用函数无需额外类型断言参数类型为any它接受任意值因此可以安全地用于检测来自外部输入、回调参数等不可信来源的值。es-toolkit 还提供了与之等价的 lodash 兼容版本 src/compat/predicate/isFunction.ts实现完全一致并通过 src/browser.ts 在浏览器构建入口中导出方便在浏览器环境下直接使用。使用方法检测所有类型的函数isFunction的最大特点是覆盖面广可以检测所有类型的函数。在 src/predicate/isFunction.spec.ts 的测试用例中覆盖了普通函数、异步函数、生成器函数与Proxy构造函数等典型场景。普通函数import { isFunction } from es-toolkit/predicate; // 普通函数 console.log(isFunction(function () {})); // true console.log(isFunction(() {})); // true console.log(isFunction(Array.prototype.slice)); // true其中Array.prototype.slice是方法引用method reference在 JavaScript 中方法本身也是函数因此同样返回true。异步函数与生成器函数// 异步函数 console.log(isFunction(async function () {})); // true console.log(isFunction(async () {})); // true // 生成器函数 console.log(isFunction(function* () {})); // trueasync函数与function*生成器虽然调用方式特殊但它们的typeof结果依然是function因此会被正确识别。测试代码 src/predicate/isFunction.spec.ts 明确验证了这两类函数it(should return true for async functions, () { const asyncFunc async function () {}; expect(isFunction(asyncFunc)).toBe(typeof asyncFunc function); }); it(should return true for generator functions, () { const genFunc function* () {}; expect(isFunction(genFunc)).toBe(typeof genFunc function); });构造函数// 构造函数 console.log(isFunction(Array)); // true console.log(isFunction(Date)); // true console.log(isFunction(RegExp)); // true console.log(isFunction(Promise)); // trueArray、Date、RegExp、Promise这些内置构造函数本质都是函数对象需要配合new调用因此全部返回true。检测内置 JavaScript 函数与类isFunction同样适用于 JavaScript 内置的各类构造函数、类型化数组构造器以及 Proxy/Reflect 相关对象// 内置构造函数 console.log(isFunction(Object)); // true console.log(isFunction(String)); // true console.log(isFunction(Number)); // true console.log(isFunction(Boolean)); // true // 类型化数组构造函数 console.log(isFunction(Int8Array)); // true console.log(isFunction(Uint8Array)); // true console.log(isFunction(Float32Array)); // true // Proxy 与 Reflect console.log(isFunction(Proxy)); // true console.log(isFunction(Reflect.get)); // true值得注意的是类型化数组构造器这一边界情况。在 src/predicate/isFunction.spec.ts 中测试对Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Uint16Array、Int32Array、Uint32Array、Float32Array、Float64Array以及DataView等全部类型化数组构造器逐一断言其期望值与Object.prototype.toString.call(type) [object Function]的结果逐项对齐。这表明isFunction的结果与标准标签检测tag check完全一致行为可预期。与看起来像函数的值区分开isFunction只认typeof function因此对非函数值一律返回false// 非函数值 console.log(isFunction({})); // false console.log(isFunction([])); // false console.log(isFunction(text)); // false console.log(isFunction(42)); // false console.log(isFunction(null)); // false console.log(isFunction(undefined)); // false // 看起来像函数但不是函数 console.log(isFunction({ call: function () {} })); // false最后一例尤其值得注意{ call: function () {} }拥有名为call的方法外形上可调用但它是一个普通对象而非函数typeof结果为object因此被正确判定为false。这正体现了isFunction严格基于语言级typeof语义、不做任何长得像就算的宽松推断。在 src/predicate/isFunction.spec.ts 中测试还利用falsey与args两个内部测试辅助位于 src/compat/_internal 目录对false、0、、null、undefined、NaN以及类数组arguments对象进行了批量验证全部返回false对象、数组、日期、错误、正则、字符串、数字、Symbol 等类型也逐一覆盖。实战场景回调验证与动态函数调用场景一回调函数的类型安全验证在处理可选回调参数时isFunction结合 TypeScript 类型谓词可以消除回调可能不是函数的不确定性function processData(data: any[], callback?: unknown) { const result data.map(item item * 2); if (isFunction(callback)) { // 这里 callback 已被收窄为函数类型可以安全调用 callback(result); } return result; }由于isFunction的返回类型是value is (...args: any[]) anyif分支内 TypeScript 编译器会自动将callback视为可调用函数无需手动断言。场景二动态函数执行当从配置、插件系统或用户输入中拿到一个可能是函数的值时可以用它做动态分发function executeIfFunction(fn: unknown, ...args: any[]) { if (isFunction(fn)) { return fn(...args); } console.log(给定值不是函数); return null; }场景三方法链中的函数确认在链式 API 设计中先用isFunction校验参数再执行映射可以避免传入非法值时抛出难以定位的错误const utils { data: [1, 2, 3], process(fn: unknown) { if (isFunction(fn)) { this.data this.data.map(fn); } return this; }, };参数与返回值项目说明参数value类型unknown待检测是否为函数的任意值返回值类型value is (...args: any[]) any值为函数时返回true否则返回false类型谓词签名意味着返回值同时承担布尔判断与类型收窄双重职责这是 es-toolkit 谓词系列如isString、isNumber、isPlainObject等共有的设计模式统一通过 src/predicate/index.ts 对外导出。在 es-toolkit 内部的实际复用isFunction不只是独立工具它还被 es-toolkit 内部多个高阶函数复用这从侧面印证了它的可靠性与基础地位。在 lodash 兼容层 src/compat 中invokeMap.ts当path本身是函数时isFunction用于判断是直接调用还是走属性路径解析wrap.ts用它决定wrapper参数是否为函数否则回退为恒等函数identitycond.ts在条件函数列表中校验每个元素是否为函数bindAll.ts过滤出对象上可绑定的函数属性functionsIn.ts遍历对象属性时用isFunction筛选函数型属性transform.ts判断对象构造器是否有效。此外memoize.spec.ts 等测试也会用isFunction来断言记忆化函数仍保持函数身份。这些内部使用点说明isFunction是构建bindAll、wrap、cond、invokeMap等复合工具时的公共地基其单行实现以typeof这一语言原语保证了极低的运行时开销——这也是 es-toolkit 追求小而快性能目标的一个缩影。小结isFunction用一行typeof value function实现了对所有函数类型的完备检测并通过类型谓词让 TypeScript 开发者在运行时校验的同时获得编译期类型收窄。无论是处理可选回调、动态调用、方法链设计还是理解 es-toolkit 内部wrap、cond、bindAll等函数的实现它都是值得深入掌握的入门级但高频复用的工具函数。安装 es-toolkit 后即可通过import { isFunction } from es-toolkit/predicate直接使用。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表