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

相关推荐
codingandsleeping4 分钟前
Express入门
javascript·后端·node.js
Vaclee6 分钟前
JavaScript-基础语法
开发语言·javascript·ecmascript
拉不动的猪28 分钟前
前端常见数组分析
前端·javascript·面试
小吕学编程1 小时前
ES练习册
java·前端·elasticsearch
Asthenia04121 小时前
Netty编解码器详解与实战
前端
袁煦丞1 小时前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛2 小时前
vue组件间通信
前端·javascript·vue.js
一笑code2 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员3 小时前
layui时间范围
前端·javascript·layui
NoneCoder3 小时前
HTML响应式网页设计与跨平台适配
前端·html