Lodash源码阅读-keysIn

Lodash 源码阅读-keysIn

功能概述

keysIn 是 Lodash 中的一个实用函数,用于获取对象的所有可枚举属性名,包括对象自身的属性和从原型链继承的属性。与 keys 函数(只返回对象自身属性)不同,keysIn 会遍历整个原型链,返回所有可访问的属性名数组。

这个函数是处理对象属性时非常有用的工具,特别是在需要考虑继承属性的场景中。

前置学习

依赖函数

  • baseKeysIn:内部实现函数,用于处理复杂对象的属性获取
  • isArrayLike:检查值是否类似数组结构的辅助函数
  • arrayLikeKeys:处理类数组对象的属性获取,第二个参数为 true 时包含继承属性

源码实现

javascript 复制代码
function keysIn(object) {
  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
}

实现思路

keysIn 函数的实现思路非常简洁明了:

  1. 判断输入值是否为类数组对象

    • 如果是类数组对象,使用 arrayLikeKeys 函数处理,并传入 true 参数表示包含继承的属性
    • 这种情况适用于数组、字符串、arguments 对象、类型化数组(如 Int8Array)等具有 length 属性且 length 为非负整数的数据结构
  2. 如果不是类数组对象,调用 baseKeysIn 函数处理普通对象

    • baseKeysIn 会处理所有可枚举的属性,包括继承的

源码解析

让我们逐行分析 keysIn 函数的实现:

javascript 复制代码
function keysIn(object) {

函数定义,接收一个 object 参数,这个参数可以是任何类型的值(包括 null 和 undefined)。

javascript 复制代码
return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);

这是一个三元条件表达式,根据 object 是否为类数组对象进行不同的处理:

类数组对象处理

如果 isArrayLike(object) 返回 true,说明 object 是一个类数组对象,那么调用 arrayLikeKeys(object, true) 处理。

arrayLikeKeys 函数专门用于处理类数组对象的属性获取,第二个参数 true 表示需要包含继承的属性。对于类数组对象,它的处理逻辑如下:

  • 创建一个空数组用于存储结果
  • 遍历类数组对象的索引,将每个有效索引添加到结果数组
  • 如果第二个参数为 true,则还会通过 for...in 循环获取继承的属性
  • 返回最终的属性名数组

示例:

javascript 复制代码
// 类数组对象示例
const str = "hello";
console.log(_.keysIn(str)); // ['0', '1', '2', '3', '4', ...继承的属性]

const arr = [1, 2, 3];
console.log(_.keysIn(arr)); // ['0', '1', '2', 'length', ...Array 原型上的方法名]

普通对象处理

如果 isArrayLike(object) 返回 false,说明 object 是普通对象(或非对象值),那么调用 baseKeysIn(object) 处理。

baseKeysIn 函数的实现我们在《Lodash 源码阅读-baseKeysIn》中已经详细分析过,它会:

  • 检查输入值是否为对象
  • 使用 for...in 循环遍历所有可枚举属性(包括继承的)
  • 特殊处理 constructor 属性
  • 返回包含所有属性名的数组

示例:

javascript 复制代码
// 普通对象示例
const obj = { a: 1, b: 2 };
console.log(_.keysIn(obj)); // ['a', 'b', ...Object 原型上的可枚举属性]

// 自定义原型链
const proto = { z: 3 };
const child = Object.create(proto);
child.x = 1;
child.y = 2;
console.log(_.keysIn(child)); // ['x', 'y', 'z', ...Object 原型上的可枚举属性]

与 keys 函数的区别

keysIn 和 Lodash 的 keys 函数是一对相关但功能不同的函数:

javascript 复制代码
// keys 函数(只返回自身属性)
_.keys({ a: 1, b: 2 }); // ['a', 'b']

// keysIn 函数(返回自身和继承属性)
_.keysIn({ a: 1, b: 2 }); // ['a', 'b', ...继承的可枚举属性]

主要区别:

  1. keys 仅返回对象自身的可枚举属性,不包括继承的属性
  2. keysIn 返回对象自身和继承的所有可枚举属性
  3. keys 在内部使用 baseKeys,而 keysIn 使用 baseKeysIn
  4. keys 的行为类似于 Object.keys(),而 keysIn 的行为类似于使用 for...in 循环

总结

keysIn 是 Lodash 库中一个用于获取对象所有可枚举属性名(包括继承的)的实用函数。通过对不同类型输入的智能处理,它提供了一种简单而强大的方式来访问对象的完整属性集。

keysIn 函数在以下场景特别有用:

  • 深度克隆需要保留原型链属性的对象
  • 合并配置对象时考虑继承的默认值
  • 验证包括继承属性在内的所有属性
  • 检查对象(包括其原型链)是否包含特定属性
相关推荐
时间的情敌16 分钟前
基于 Vue3 及TypeScript 项目后的总结
前端·vue.js·typescript
lpfasd12321 分钟前
从 Electron 转向 Tauri:用 Rust 打造更轻、更快的桌面应用
javascript·rust·electron
纯爱掌门人36 分钟前
鸿蒙端云一体化云存储实战:手把手教你玩转文件上传下载
前端·harmonyos
非凡ghost38 分钟前
图吧工具箱-电脑硬件圈的“瑞士军刀”
前端·javascript·后端
非凡ghost39 分钟前
Xrecode3(多功能音频转换工具)
前端·javascript·后端
橙某人41 分钟前
飞书多维表格插件:进一步封装,提升开发效率!🚀
前端·javascript
他们叫我秃子1 小时前
从 0 到 1,我用小程序 + 云开发打造了一个“记忆瓶子”,记录那些重要的日子!
前端·微信小程序·小程序·云开发
非凡ghost1 小时前
Subtitle Edit(字幕编辑软件) 中文绿色版
前端·javascript·后端
用户84298142418101 小时前
10个JavaScript编程实用技巧
javascript
扎瓦斯柯瑞迫1 小时前
cursor: 10分钟魔改环境、优雅获取Token
前端·javascript·后端