Lodash源码阅读-nativeKeys

功能概述

nativeKeys 函数是 Lodash 中用于获取对象自身可枚举属性名的工具函数。它是对原生 Object.keys 方法的包装,通过 overArg 函数实现了对输入参数的预处理,使其能更安全地处理各种类型的输入。

源码实现

js 复制代码
// 使用 overArg 函数包装 Object.keys
var nativeKeys = overArg(Object.keys, Object);

// overArg 函数的实现
function overArg(func, transform) {
  return function(arg) {
    return func(transform(arg));
  };
}

实现原理解析

原理概述

nativeKeys 函数的核心思想是在调用 Object.keys 之前,先对输入参数进行预处理。它通过 overArg 函数创建了一个新函数,这个新函数会:

  1. 先使用 Object 构造函数将输入参数转换为对象
  2. 然后将转换后的结果传给 Object.keys

这样的设计可以让我们更安全地处理各种类型的输入值,避免直接调用 Object.keys 可能出现的错误。

代码解析

1. overArg 函数的作用

js 复制代码
function overArg(func, transform) {
  return function(arg) {
    return func(transform(arg));
  };
}

overArg 函数是一个高阶函数,它接收两个参数:

  1. func:要执行的主函数(这里是 Object.keys)
  2. transform:转换函数(这里是 Object 构造函数)

示例:

js 复制代码
// 创建一个简单的 overArg 使用示例
const double = x => x * 2;
const addOne = x => x + 1;
const doubleAfterAddOne = overArg(double, addOne);

console.log(doubleAfterAddOne(5)); // 12
// 执行过程:
// 1. addOne(5) => 6
// 2. double(6) => 12

2. Object 构造函数的转换作用

使用 Object 构造函数可以将各种类型的值转换为对象:

js 复制代码
// 原始类型转换
console.log(Object(42));        // Number {42}
console.log(Object('hello'));   // String {'hello'}
console.log(Object(true));      // Boolean {true}

// null 和 undefined 的处理
console.log(Object(null));      // {}
console.log(Object(undefined)); // {}

// 对象类型会保持不变
const obj = { x: 1 };
console.log(Object(obj) === obj); // true

3. nativeKeys 的实际应用

js 复制代码
// 1. 处理普通对象
const obj = { a: 1, b: 2 };
console.log(nativeKeys(obj)); // ['a', 'b']

// 2. 处理数组
const arr = ['a', 'b', 'c'];
console.log(nativeKeys(arr)); // ['0', '1', '2']

// 3. 处理字符串
console.log(nativeKeys('hello')); // ['0', '1', '2', '3', '4']

// 4. 处理数字(会先转换为对象)
console.log(nativeKeys(42)); // []

// 5. 处理 null/undefined(安全处理)
console.log(nativeKeys(null)); // []
console.log(nativeKeys(undefined)); // []

// 6. 处理特殊对象
class Person {
  constructor(name) {
    this.name = name;
  }
}
const person = new Person('张三');
console.log(nativeKeys(person)); // ['name']

注意事项

  1. nativeKeys 只返回对象自身的可枚举属性,不包含原型链上的属性
js 复制代码
const parent = { x: 1 };
const child = Object.create(parent);
child.y = 2;

console.log(nativeKeys(child)); // ['y']
// x 不会被返回,因为它在原型链上
  1. Symbol 类型的属性会被忽略
js 复制代码
const obj = {
  [Symbol('a')]: 1,
  b: 2
};

console.log(nativeKeys(obj)); // ['b']
// Symbol 属性不会出现在结果中
  1. 不可枚举的属性也会被忽略
js 复制代码
const obj = {};
Object.defineProperty(obj, 'hidden', {
  value: 'secret',
  enumerable: false
});

console.log(nativeKeys(obj)); // []
// hidden 属性不会出现在结果中,因为它是不可枚举的

总结

nativeKeys 函数通过巧妙地使用 overArg 和 Object 构造函数,实现了一个更安全、更可靠的属性名获取方法。它的主要特点是:

  1. 安全处理:可以处理任意类型的输入,包括 null 和 undefined
  2. 类型转换:通过 Object 构造函数自动进行类型转换
  3. 属性过滤:只返回自身的可枚举属性
  4. 实现简单:代码简洁但功能强大

这个函数在 Lodash 中经常被用作其他函数的基础工具,是一个非常实用的辅助函数。

相关推荐
不知几秋3 分钟前
Spring Boot
java·前端·spring boot
程序猿ZhangSir7 分钟前
Vue3 项目的基本架构解读
前端·javascript·vue.js
HarderCoder11 分钟前
ByAI: Redux的typescript简化实现
前端
90后的晨仔18 分钟前
RxSwift 框架解析
前端·ios
我命由我1234524 分钟前
VSCode - VSCode 放大与缩小代码
前端·ide·windows·vscode·前端框架·编辑器·软件工具
Mintopia32 分钟前
当数字橡皮泥遇上魔法:探秘计算机图形学的细分曲面
前端·javascript·计算机图形学
Mintopia40 分钟前
Three.js 物理引擎:给你的 3D 世界装上 “牛顿之魂”
前端·javascript·three.js
Jeremy_Lee12343 分钟前
grafana 批量视图备份及恢复(含数据源)
前端·网络·grafana
import_random1 小时前
[python]conda
前端
亲亲小宝宝鸭1 小时前
写了两个小需求,终于搞清楚了表格合并
前端·vue.js