Lodash源码阅读-baseUnary

Lodash 源码阅读-baseUnary

概述

baseUnary 是 Lodash 的内部工具函数,用于将任意函数转换成只接收一个参数的函数。它创建一个函数包装器,无论原始函数设计为接收多少个参数,包装后的函数只会接收并传递第一个参数。这种转换在函数式编程和函数组合场景中特别有用。

前置学习

依赖函数

baseUnary 是基础函数,不依赖其他 Lodash 函数。

技术知识

  • 高阶函数:函数可以作为参数和返回值
  • 闭包:函数能够访问其外部作用域中的变量
  • 一元函数:只接受一个参数的函数

源码实现

js 复制代码
function baseUnary(func) {
  return function (value) {
    return func(value);
  };
}

实现思路

baseUnary 的实现简单明了:接收一个函数作为参数,返回一个新函数。这个新函数只接收一个参数,并将这个参数传给原函数,然后返回原函数的执行结果。通过这种方式,任何函数都可以被转换为严格的一元函数。

源码解析

函数签名:

js 复制代码
function baseUnary(func)
  • func: 要转换的原始函数

实现细节:

  1. 返回一个新函数,只接收一个参数 value
  2. 在新函数内部,调用原始函数 func 并只传入 value 参数
  3. 返回原始函数的执行结果

这个设计使用了闭包机制,新函数可以访问外部 baseUnary 函数作用域中的 func 变量。

应用场景

baseUnary 在 Lodash 中主要用于以下场景:

  1. 修复 parseInt 问题
js 复制代码
// 直接使用 parseInt 会有问题
const numbers = ["1", "2", "3"].map(parseInt);
// 结果: [1, NaN, NaN],因为 parseInt 接收两个参数(字符串和进制),而 map 会传递三个参数(当前值、索引、数组)给回调函数。
// 所以实际执行了:parseInt("1", 0, arr)、parseInt("2", 1, arr)、parseInt("3", 2, arr)
// 其中第二个参数被当作进制,1不是有效进制,2进制中没有"3",所以后两个结果为NaN

// 使用 baseUnary 修复
const numbers = ["1", "2", "3"].map(baseUnary(parseInt));
// 结果: [1, 2, 3],只传递第一个参数
  1. 简化函数调用
js 复制代码
// 原始函数接收多个参数
function add(a, b) {
  return a + b;
}

// 使用 baseUnary 转换为只接收一个参数
const addOne = baseUnary(add);
// 现在 addOne 只接收一个参数,第二个参数会被忽略
console.log(addOne(5)); // 5 + undefined = NaN
  1. 统一函数接口
js 复制代码
// 假设我们有一组函数,有些接收一个参数,有些接收多个
const functions = [(x) => x * 2, (x, y) => x + y, (x) => x - 1];

// 使用 baseUnary 统一接口
const unifiedFunctions = functions.map(baseUnary);
// 现在所有函数都只接收一个参数
  1. 数组处理
js 复制代码
// 处理数组时确保函数只接收一个参数
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(baseUnary((x) => x * 2));
// 结果: [2, 4, 6, 8, 10]

总结

baseUnary 尽管实现简单,但在函数式编程中具有重要作用:

  1. 简化函数接口:通过限制参数数量,使函数调用更加清晰和可预测
  2. 解决参数不匹配问题 :特别是在处理像 parseInt 这样的函数时,避免因额外参数导致的意外行为
  3. 促进函数组合:为函数组合链提供统一的函数接口规范

这个工具函数展示了 Lodash 设计理念中的重要原则:通过简单的转换函数增强代码的灵活性和复用性,使开发者能够更容易地组合和转换函数以适应不同场景。

相关推荐
你的人类朋友2 小时前
✍️记录自己的git分支管理实践
前端·git·后端
合作小小程序员小小店2 小时前
web网页开发,在线考勤管理系统,基于Idea,html,css,vue,java,springboot,mysql
java·前端·vue.js·后端·intellij-idea·springboot
防火墙在线2 小时前
前后端通信加解密(Web Crypto API )
前端·vue.js·网络协议·node.js·express
Jacky-0082 小时前
Node + vite + React 创建项目
前端·react.js·前端框架
CoderYanger3 小时前
前端基础——CSS练习项目:百度热榜实现
开发语言·前端·css·百度·html·1024程序员节
i_am_a_div_日积月累_3 小时前
10个css更新
前端·css
她是太阳,好耀眼i4 小时前
Nvm 实现vue版本切换
javascript·vue.js·ecmascript
蒲公英10014 小时前
在wps软件的word中使用js宏命令设置表格背景色
javascript·word·wps
倚栏听风雨4 小时前
npm命令详解
前端
用户47949283569154 小时前
为什么我的react项目启动后,dom上的类名里没有代码位置信息
前端·react.js