Lodash源码阅读-baseAt

Lodash 源码阅读-baseAt

概述

baseAt 是 Lodash 内部的基础函数,用来批量获取对象中多个路径的值,并把这些值组成一个新数组返回。

前置学习

依赖函数

  • get:安全地获取对象指定路径的值,即使中间路径不存在也不会报错

技术知识

  • 数组操作:创建和填充数组的方法
  • while 循环:使用前置递增运算符的循环写法
  • 短路检查 :使用 object == null 同时检查 nullundefined
  • 三元运算符:简化条件逻辑的表达方式

源码实现

javascript 复制代码
/**
 * The base implementation of `at` without support for individual paths.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {string[]} paths The property paths of elements to pick.
 * @returns {Array} Returns the picked elements.
 */
function baseAt(object, paths) {
  var index = -1,
    length = paths.length,
    result = Array(length),
    skip = object == null;

  while (++index < length) {
    result[index] = skip ? undefined : get(object, paths[index]);
  }
  return result;
}

export default baseAt;

实现思路

baseAt 函数接收一个对象和一组路径数组,然后遍历所有路径,从对象中提取每个路径对应的值。如果对象为空(null 或 undefined),则会跳过实际获取过程,直接用 undefined 填充结果数组。函数通过一次遍历就完成了所有路径的值获取,最后返回这些值组成的新数组。

源码解析

javascript 复制代码
function baseAt(object, paths) {
  // 初始化变量
  var index = -1, // 循环索引,从-1开始是为了配合前置++运算符
    length = paths.length, // 路径数组长度
    result = Array(length), // 预分配结果数组空间,提高性能
    skip = object == null; // 判断对象是否为null或undefined
}

while (++index < length) {
  result[index] = skip ? undefined : get(object, paths[index]);
}

这段代码初始化了函数需要的变量:

  • index 设为 -1,配合后面循环中的前置 ++ 操作
  • length 保存路径数组的长度
  • result 预创建了一个指定长度的数组,比动态扩容更高效
  • skip 标记对象是否为 null 或 undefined
javascript 复制代码
while (++index < length) {
  result[index] = skip ? undefined : get(object, paths[index]);
}

这是函数的核心循环:

  • 使用前置 ++ 操作将 index 递增,同时作为循环条件的一部分
  • 对于每个路径,使用三元运算符决定结果:
    • 如果 skip 为 true(对象为 null 或 undefined),直接填入 undefined
    • 否则调用 get(object, paths[index]) 获取对应路径的值
  • 这种方式避免了在对象为空时多次调用 get 函数,是一种性能优化
javascript 复制代码
  return result;
}

最后返回填充完毕的结果数组。

关键点分析

  1. 性能优化

    • 使用 Array(length) 预分配数组空间而不是用 push 动态增长
    • 使用 skip 标记避免在对象为空时多次调用 get 函数
  2. 安全性

    • 通过 get 函数安全地获取嵌套属性,不会因为路径不存在而报错
    • 对象本身为 null/undefined 时的特殊处理
  3. 代码简洁

    • 使用三元运算符简化条件逻辑
    • 整个函数主体只有一个简单的循环

应用示例

javascript 复制代码
// 示例对象
const obj = {
  user: {
    name: "John",
    profile: {
      age: 28,
      address: {
        city: "New York",
      },
    },
  },
  posts: [
    { id: 1, title: "Hello" },
    { id: 2, title: "World" },
  ],
};

// 获取多个路径的值
baseAt(obj, [
  "user.name",
  "user.profile.age",
  "posts[0].title",
  "missing.path",
]);
// => ['John', 28, 'Hello', undefined]

// 对象为null的情况
baseAt(null, ["a", "b", "c"]);
// => [undefined, undefined, undefined]

总结

baseAt 函数是 Lodash 中 _.at 方法的核心实现,它通过巧妙的方式实现了批量获取对象属性的功能。函数设计简单高效,通过预分配结果数组和条件跳过来优化性能,同时依靠 get 函数确保了属性访问的安全性。这个函数体现了 Lodash 中对性能和健壮性的平衡考虑,既快速又可靠。

相关推荐
爱分享的程序员37 分钟前
全栈架构设计图
前端
KenXu1 小时前
YYEVA WebGPU 渲染实现技术解析
前端·webgl
~卷心菜~1 小时前
CSS基础-即学即用 -- 笔记1
前端·css·笔记
我最厉害。,。1 小时前
CSRF 请求伪造&Referer 同源&置空&配合 XSS&Token 值校验&复用删除
前端·xss·csrf
vvilkim1 小时前
深入解析React.lazy与Suspense:现代React应用的性能优化利器
前端·react.js·前端框架
野猪亨利2581 小时前
【JS 小白也能懂】回调函数:让代码学会「听话办事」的魔法
前端
dengzy3211 小时前
js 观察者模式和发布订阅模式详解
javascript
五号厂房1 小时前
前端接口编写的最佳实践总结:设计、实现、维护全流程
前端
Cutey9161 小时前
Vue 实现多语言国际化的完整指南
前端·javascript·面试
广龙宇1 小时前
【Web API系列】Web Shared Storage API 深度解析:WindowSharedStorage 接口实战指南
前端