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 函数在以下场景特别有用:

  • 深度克隆需要保留原型链属性的对象
  • 合并配置对象时考虑继承的默认值
  • 验证包括继承属性在内的所有属性
  • 检查对象(包括其原型链)是否包含特定属性
相关推荐
原则猫8 小时前
UDP 到底怎么实现可靠的
前端
Java后端的Ai之路8 小时前
14、ReactJS - 路由(Router)
前端·react.js·状态模式
持敬chijing8 小时前
白盒测试与代码审计-js登录逆向实战
javascript·网络·安全·web安全·网络安全·网络攻击模型
优选资源分享9 小时前
PicGo v3.0.3 新版 | 开源免费图床工具
javascript·笔记·electron
裕晟资质规划9 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
ShineWinsu9 小时前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
月夏9 小时前
Vue3 转 React:18 项对照表 + 5 个必踩的坑(附 7 天上手路线)
前端
广州华水科技10 小时前
单北斗GNSS位移监测系统的应用与维护解析
前端
普通人610 小时前
php+html+canvas实现树状打开的结构
开发语言·javascript·html5·1024程序员节
梦曦i10 小时前
uni-storage 0.1.0 发布:TTL过期管理+多实例隔离
前端·storage·uni-app x