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 中经常被用作其他函数的基础工具,是一个非常实用的辅助函数。

相关推荐
slongzhang_1 小时前
html添加水印
前端·html
Small black human2 小时前
前端-什么是Vue
前端·javascript·vue.js
IT 前端 张2 小时前
Axios与Ajax:现代Web请求大比拼
前端·javascript·ajax
ikun778g3 小时前
uniapp使用uview UI,自定义级联选择组件
前端·前端框架·uni-app
java水泥工3 小时前
基于Echarts+HTML5可视化数据大屏展示-惠民服务平台
前端·echarts·html5
万少4 小时前
可可图片编辑 HarmonyOS(3)应用间分享图片
前端·harmonyos·客户端
Hy行者勇哥4 小时前
现代软件系统架构:前端、后端、数据库、部署、算法与AI学习的结构与交互分析
前端·数据库·学习
前端开发爱好者5 小时前
90% 前端都不知道的 20 个「零依赖」浏览器原生能力!
前端·javascript·vue.js
讨厌吃蛋黄酥5 小时前
React语法全景指南:面试官问我用了哪些语法时,我这样回答拿到了offer
前端·react.js·面试
Bling_Bling_15 小时前
面试常考css:三列布局实现方式
前端·html·css3