Lodash源码阅读-getAllKeys

Lodash 源码阅读-getAllKeys

功能概述

getAllKeys 是 Lodash 库中的一个内部工具函数,它的主要作用是创建一个包含目标对象自身所有可枚举属性名和 Symbol 属性的数组。与 keys 函数不同,getAllKeys 不仅返回普通的字符串键,还会返回 Symbol 类型的键,使其成为获取对象完整键集合的有力工具。

前置学习

依赖关系

getAllKeys 函数依赖以下几个函数和变量:

  • baseGetAllKeys:一个基础实现函数,用于获取对象的属性名和 Symbol
  • keys:获取对象自身的可枚举属性名
  • getSymbols:获取对象自身的可枚举 Symbol 属性
  • arrayPush:将一个数组的元素添加到另一个数组中

技术知识

  • ES6 Symbol:JavaScript 中的原始数据类型,表示唯一的标识符
  • 可枚举属性:JavaScript 对象的属性可以是可枚举的或不可枚举的,可枚举属性可以通过 for...in 循环遍历
  • 函数组合:通过组合多个函数来实现复杂功能的编程模式

源码实现

javascript 复制代码
/**
 * Creates an array of own enumerable property names and symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names and symbols.
 */
function getAllKeys(object) {
  return baseGetAllKeys(object, keys, getSymbols);
}

实现思路

getAllKeys 函数的实现思路非常简洁明了,它通过调用 baseGetAllKeys 函数,并传入三个参数:

  1. 要查询的对象 object
  2. 获取对象属性名的函数 keys
  3. 获取对象 Symbol 属性的函数 getSymbols

baseGetAllKeys 函数会先使用 keys 函数获取对象的所有可枚举属性名,然后使用 getSymbols 函数获取对象的所有可枚举 Symbol 属性,最后将两者合并返回。这种实现方式通过函数组合的方式,将获取不同类型键的逻辑分离,使代码更加清晰和可维护。

源码解析

函数签名

javascript 复制代码
function getAllKeys(object) {

函数接收一个参数:

  • object:要查询的对象,可以是任何类型的值

调用 baseGetAllKeys

javascript 复制代码
return baseGetAllKeys(object, keys, getSymbols);

这行代码是函数的核心,它调用 baseGetAllKeys 函数,并传入三个参数:

  1. object:要查询的对象
  2. keys:获取对象属性名的函数
  3. getSymbols:获取对象 Symbol 属性的函数

baseGetAllKeys 的实现

javascript 复制代码
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  var result = keysFunc(object);
  return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
}

baseGetAllKeys 函数的实现包括以下步骤:

  1. 调用 keysFunc(即 keys函数)获取对象的所有可枚举属性名,并将结果存储在 result 变量中
  2. 检查 object 是否为数组:
    • 如果是数组,直接返回 result(因为数组通常不会有 Symbol 属性)
    • 如果不是数组,调用 symbolsFunc(即 getSymbols函数)获取对象的所有可枚举 Symbol 属性,然后使用 arrayPush 将其添加到 result 中,最后返回合并后的结果

与其他函数的比较

getAllKeys 函数与 Lodash 中的其他类似函数有一些重要区别:

  1. keys vs getAllKeys

    • keys 只返回对象自身的可枚举字符串属性名
    • getAllKeys 返回对象自身的可枚举字符串属性名和 Symbol 属性
    javascript 复制代码
    const sym = Symbol("test");
    const obj = { a: 1, [sym]: 2 };
    
    console.log(_.keys(obj)); // ['a']
    console.log(_.getAllKeys(obj)); // ['a', Symbol(test)]
  2. Object.keys vs getAllKeys

    • Object.keys 只返回对象自身的可枚举字符串属性名
    • getAllKeys 返回对象自身的可枚举字符串属性名和 Symbol 属性
    javascript 复制代码
    const sym = Symbol("test");
    const obj = { a: 1, [sym]: 2 };
    
    console.log(Object.keys(obj)); // ['a']
    console.log(_.getAllKeys(obj)); // ['a', Symbol(test)]
  3. Object.getOwnPropertyNames vs getAllKeys

    • Object.getOwnPropertyNames 返回对象自身的所有字符串属性名(包括不可枚举的)
    • getAllKeys 只返回对象自身的可枚举字符串属性名和 Symbol 属性
    javascript 复制代码
    const obj = {};
    Object.defineProperty(obj, "a", { value: 1, enumerable: false });
    const sym = Symbol("test");
    obj[sym] = 2;
    
    console.log(Object.getOwnPropertyNames(obj)); // ['a']
    console.log(_.getAllKeys(obj)); // [Symbol(test)]

总结

getAllKeys 是 Lodash 中一个强大而实用的内部工具函数,它通过组合 keysgetSymbols 函数,提供了一种获取对象所有可枚举键(包括 Symbol)的简洁方法。

这个函数的设计体现了几个重要的软件工程原则:

  1. 单一职责:函数只负责一件事情 - 获取对象的所有可枚举键
  2. 函数组合:通过组合多个专门的函数来实现复杂功能
  3. 代码复用 :利用已有的 baseGetAllKeyskeysgetSymbols 函数,避免重复代码
  4. 抽象层次:提供了比原生方法更高级的抽象,简化了获取所有类型键的过程
相关推荐
2601_9539880718 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·后端·物联网·tcp/ip·数学建模·前端框架
天空之城--18 小时前
Claude Code 高效开发 Web 2D/3D 完全指南:心法、自定义 Skill 体系与社区技能包实战
前端·3d
breeze jiang18 小时前
Next.js App Router 父子组件 RSC 拆分实战:从 Redis Hash 到客户端交互的最小化边界
javascript·redis·哈希算法
IT_陈寒18 小时前
SpringBoot自动配置坑了我三天,原来漏了这个注解
前端·人工智能·后端
丫头,冲鸭!!!18 小时前
记账网站-post功能
javascript·个人开发
鬼手点金18 小时前
Scrapy + Playwright 完整示例(JS 动态渲染网页)
开发语言·javascript·爬虫·python·scrapy·html·json
逝水无殇19 小时前
HTML 文本格式化详解:掌握 <strong>、<em>、<mark>、<del> 等常用标签
前端·javascript·html
特立独行的猫a19 小时前
DeepSeek Harness插件和工具的区别介绍及开发入门指南
前端·ai·agent·插件·deepseek·harness
小新讲网安19 小时前
HTTP请求走私攻击实战:CL.TE与TE.CL绕过前端服务器全解析
服务器·前端·网络·web安全·http·架构·漏洞
风骏时光牛马19 小时前
AI办公系统异常事件复盘分析
前端