Lodash 源码阅读-get
概述
get
是 Lodash 库中用于安全获取嵌套对象属性值的函数。它允许我们从深层嵌套的对象中获取属性,不必担心中间路径不存在而导致的错误,同时支持提供默认值作为备选返回结果。
前置学习
依赖函数
baseGet
:核心实现,根据路径从对象中获取值的内部函数castPath
:将属性路径转换为标准化的数组形式toKey
:将路径片段转换为合法的对象属性键
技术知识
- 路径访问:JavaScript 中的对象属性访问方式
- 空值处理:处理 null 和 undefined 的技巧
- 短路求值:JavaScript 中的逻辑短路求值原理
源码实现
javascript
/**
* Gets the value at `path` of `object`. If the resolved value is
* `undefined`, the `defaultValue` is returned in its place.
*
* @static
* @memberOf _
* @since 3.7.0
* @category Object
* @param {Object} object The object to query.
* @param {Array|string} path The path of the property to get.
* @param {*} [defaultValue] The value returned for `undefined` resolved values.
* @returns {*} Returns the resolved value.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }] };
*
* _.get(object, 'a[0].b.c');
* // => 3
*
* _.get(object, ['a', '0', 'b', 'c']);
* // => 3
*
* _.get(object, 'a.b.c', 'default');
* // => 'default'
*/
function get(object, path, defaultValue) {
var result = object == null ? undefined : baseGet(object, path);
return result === undefined ? defaultValue : result;
}
实现思路
get
函数的实现思路非常直接:
- 首先检查对象是否为 null 或 undefined,如果是则直接返回 undefined
- 如果对象有效,则调用
baseGet
函数根据指定的路径获取嵌套属性值 - 检查获取到的结果是否为 undefined,如果是则返回提供的默认值,否则返回实际获取的结果
这种设计允许安全地访问任意深度的嵌套对象属性,而不必担心中间路径不存在导致的错误。同时通过提供默认值参数,可以在目标值不存在时返回预设的结果,增加了函数的实用性和灵活性。
源码解析
整个函数只有一行实际代码,但它利用了多个 JavaScript 语言特性和辅助函数。让我们逐步解析:
javascript
function get(object, path, defaultValue) {
var result = object == null ? undefined : baseGet(object, path);
return result === undefined ? defaultValue : result;
}
参数解析
object
:要查询的目标对象path
:属性路径,可以是字符串形式(如'a.b.c'
或'a[0].b.c'
)或数组形式(如['a', '0', 'b', 'c']
)defaultValue
:当解析得到的值为 undefined 时返回的默认值(可选)
空值检查
javascript
object == null ? undefined : baseGet(object, path);
这行代码使用了逻辑短路操作:
object == null
检查object
是否为null
或undefined
(使用==
而不是===
来同时匹配这两种情况)- 如果条件为真,直接返回
undefined
,不调用baseGet
- 如果条件为假,则调用
baseGet(object, path)
来获取路径指定的值
这种检查避免了在对象为 null 或 undefined 时尝试访问其属性而导致的错误。
baseGet 调用
baseGet
是实际执行属性路径查找的内部函数:
javascript
// baseGet 简化版实现
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
函数首先通过 castPath
将路径转换为标准化的数组形式,然后循环遍历路径各部分,逐层获取嵌套对象的属性值。
默认值处理
javascript
return result === undefined ? defaultValue : result;
这行代码使用三元操作符检查从 baseGet
获取的结果:
- 如果结果是
undefined
(表示路径无效或值不存在),则返回提供的defaultValue
- 否则返回找到的实际值
result
这提供了一种优雅的方式来处理属性不存在的情况,避免了大量的条件检查代码。
总结
get
函数是 Lodash 中最常用、最实用的函数之一,它解决了 JavaScript 中访问深层嵌套对象属性的常见问题。其核心设计思想包括:
- 防御性编程:通过预先检查 null 和 undefined 以及提供默认值,避免运行时错误
- 路径灵活性:支持字符串和数组两种路径表示方式,增加了使用的灵活性
- 短小精悍:只有一行实际代码,但解决了一个常见的复杂问题
- 功能分离 :将核心实现放在
baseGet
中,保持get
函数的简洁
这种设计方法不仅使代码更加健壮,还大大提高了开发效率,减少了条件检查代码的编写。