Lodash源码阅读-apply

Lodash 源码阅读-apply

概述

apply 是 Lodash 内部的一个函数,它对原生的 Function.prototype.apply 方法进行了封装和优化。这个函数通过根据参数数量选择不同的调用方式,来提高函数调用的性能。

前置学习

依赖函数

apply 函数非常独立,没有依赖其他 Lodash 函数。

技术知识

  • 函数调用方式 :JavaScript 中 callapply 的区别和使用场景
  • 参数数组:如何处理和传递参数数组
  • 性能优化:通过条件判断减少函数调用开销的技巧
  • switch 语句:JavaScript 中 switch 的使用方式

源码实现

javascript 复制代码
function apply(func, thisArg, args) {
  switch (args.length) {
    case 0:
      return func.call(thisArg);
    case 1:
      return func.call(thisArg, args[0]);
    case 2:
      return func.call(thisArg, args[0], args[1]);
    case 3:
      return func.call(thisArg, args[0], args[1], args[2]);
  }
  return func.apply(thisArg, args);
}

实现思路

apply 函数的实现非常巧妙,它根据传入参数数组的长度,采用不同的调用策略:

  1. 检查参数数组 args 的长度
  2. 如果参数数量是 0 到 3 个,就直接使用 func.call,并明确列出每个参数
  3. 如果参数数量超过 3 个,则使用 func.apply 传递完整的参数数组
  4. 所有情况下都返回函数调用的结果

这种实现方式避免了 apply 在处理小参数量时的性能损失,因为 callapply 在少量参数时性能更好。

源码解析

判断参数长度

javascript 复制代码
switch (
  args.length
  // 各种情况...
) {
}

这段代码使用 switch 语句根据参数数组的长度来选择不同的处理方式。这是一种明确而高效的条件分支处理方式。

少量参数优化

javascript 复制代码
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);

这部分代码展示了优化的核心:

  • 当参数数量较少(0-3 个)时,直接使用 call 方法
  • 明确列出每个参数,避免了数组参数的解析开销
  • 每个分支直接返回函数调用的结果

例如,对于只有一个参数的情况:

javascript 复制代码
func.call(thisArg, args[0]); // 比 func.apply(thisArg, args) 更高效

默认情况处理

javascript 复制代码
return func.apply(thisArg, args);

当参数数量超过 3 个时,使用传统的 apply 方法。在这种情况下,apply 方法的性能优势开始显现,因为它可以直接接收参数数组。

`

总结

Lodash 的 apply 函数虽然简短,但却体现了几个重要的编程原则:

  1. 性能优化:根据不同的参数数量选择最高效的函数调用方式,这是一种微优化,在大量调用时能带来显著的性能提升

  2. API 设计 :保持与原生 apply 相同的接口,使得函数可以无缝替代原生方法

  3. 代码简洁 :通过 switch 语句清晰地表达了不同情况的处理逻辑,没有复杂的条件嵌套

  4. 默认情况处理:对于不在优化范围内的情况,退回到标准方法,保证了函数的通用性

这种优化方式也提醒我们,在 JavaScript 中,有时候直接使用 call 并明确列出参数,比使用 apply 和参数数组更高效,特别是在参数数量较少的情况下。

相关推荐
Larcher27 分钟前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
SheepHappy28 分钟前
MyBatis-Plus 源码阅读(二)代码生成器原理深度剖析
java·源码阅读
徐子颐40 分钟前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭1 小时前
如何理解HTML语义化
前端·html
jump6801 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信1 小时前
我们需要了解的Web Workers
前端
brzhang1 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu2 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花2 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js
十二春秋2 小时前
场景模拟:基础路由配置
前端