Lodash 源码阅读-basePropertyDeep
概述
basePropertyDeep
是 Lodash 内部的工具函数,用于创建属性访问器。它能生成一个函数,该函数接收对象并返回该对象在指定深层路径上的值。该函数与 baseProperty
互补,一起支持 Lodash 中 _.property
方法的完整功能。
前置学习
依赖函数
- baseGet:核心函数,根据路径从对象中获取深层嵌套的属性值
- castPath:将各种格式的路径(字符串、数组等)转换为统一的数组格式
- toKey:将路径片段转换为有效的对象属性键
技术知识
- 高阶函数:返回函数的函数
- 闭包:函数能够记住并访问其定义时所在的词法作用域
- 柯里化:将多参数函数转换为一系列单参数函数
- 属性路径访问:以字符串或数组形式表示的嵌套对象访问路径
源码实现
javascript
function basePropertyDeep(path) {
return function (object) {
return baseGet(object, path);
};
}
实现思路
basePropertyDeep
的实现思路非常简洁:
- 接收一个属性路径作为参数
- 返回一个新函数,该函数接收一个对象作为参数
- 在返回的函数内部,调用
baseGet
根据路径从对象中获取值
这种设计体现了函数式编程中的柯里化思想:先固定属性路径参数,创建一个可重用的访问器函数,然后在需要时传入不同的对象获取属性值。
源码解析
函数签名
javascript
function basePropertyDeep(path) {
// ...
}
函数接收一个 path
参数,表示要访问的属性路径。路径可以是字符串形式(如 'a.b.c'
)或数组形式(如 ['a', 'b', 'c']
)。
返回函数
javascript
return function (object) {
return baseGet(object, path);
};
函数返回一个新的函数,这个新函数:
- 接收一个
object
参数,表示要访问其属性的对象 - 利用闭包特性"记住"了外部函数中的
path
参数 - 调用
baseGet(object, path)
来获取对象在指定路径上的值
baseGet 函数
basePropertyDeep
本质上是对 baseGet
函数的封装:
javascript
function baseGet(object, path) {
path = castPath(path, object);
var index = 0,
length = path.length;
while (object != null && index < length) {
object = object[toKey(path[index++])];
}
return index && index == length ? object : undefined;
}
baseGet
处理实际的属性访问逻辑:
- 将路径标准化为数组格式
- 逐层访问对象的嵌套属性
- 安全处理
null
和undefined
值 - 返回找到的属性值或
undefined
与 baseProperty 对比
basePropertyDeep
和 baseProperty
是一对互补函数:
javascript
function baseProperty(key) {
return function (object) {
return object == null ? undefined : object[key];
};
}
主要区别:
baseProperty
处理单层属性访问,直接使用object[key]
语法,性能更好basePropertyDeep
处理多层嵌套属性访问,使用baseGet
进行复杂路径解析
应用场景
basePropertyDeep
在 Lodash 中主要通过 _.property
方法被使用:
javascript
// _.property 的简化实现
function property(path) {
return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
}
总结
basePropertyDeep
是一个设计精巧的函数,它通过简洁的实现提供了强大的深层属性访问能力。这个函数体现了 Lodash 的几个重要设计原则:
- 单一职责原则 :专注于创建属性访问器,将实际的属性访问逻辑委托给
baseGet
- 函数式设计:利用高阶函数和闭包,支持函数复用和组合
- 一致的接口 :与
baseProperty
保持相同的函数签名,便于在_.property
中无缝集成 - 优雅的抽象:将复杂的深层属性访问封装成简单易用的函数
通过这种设计,Lodash 提供了灵活而强大的属性访问功能,使开发者能够简洁地处理复杂数据结构,同时保持代码的可读性和可维护性。