如何实现类似 lodash.get 函数?
实现一个类似于 Lodash.get 的函数,该函数用于安全地访问嵌套对象的属性值,并提供默认值。
lodash.get函数的作用是通过路径安全地访问嵌套对象的属性值,避免因路径节点不存在(如undefined或null)而抛出错误,并提供默认值作为后备。它在处理对象结构不确定的场景时特别实用。语法为get(object, path, defaultValue)
,其中object
是目标对象,path
可以是字符串(如a.b.c
)或数组(如['a','b','c']
),defaultValue
是可选的备用返回值。
实现步骤核心要点如下:
- 参数验证:
- 首先检查
object
是否为null
或非对象类型(非object
类型),若是直接返回defaultValue
。因为lodash.get仅能操作对象结构。
- 首先检查
- 路径标准化:
- 处理
path
参数支持字符串和数组:若path
为字符串,使用正则表达式替换处理方括号索引(例如a
转化为a.0
),再以点为分隔符分割为键数组(如a.0.b
转为['a','0','b']
)。
- 处理
- 安全遍历取值:
- 基于标准化路径数组使用循环或reduce迭代器依次访问对象属性:
- 每一步检查当前对象是否可访问(是否为对象且非
null
)。 - 若某节点不可用,中断遍历并设置值为
undefined
。
- 每一步检查当前对象是否可访问(是否为对象且非
- 基于标准化路径数组使用循环或reduce迭代器依次访问对象属性:
- 返回结果:
- 若最终结果为
undefined
(代表路径无效或值未定义),返回defaultValue
;否则返回解析到的值。
- 若最终结果为
完整实现代码(简化代码清晰度):
function customGet(object, path, defaultValue) {
// 第1步:验证输入对象是否可操作
if (object === null || typeof object !== 'object') return defaultValue;
// 第2步:处理path并转为数组结构
let keyArray = [];
if (Array.isArray(path)) {
keyArray = path;
} else if (typeof path === 'string') {
// 转换路径 - 移除方括号形成统一点分隔键 (示例 "a.b"->"a.0.b"再分割为数组)
const normalizedPath = path.replace(/\[(.*?)\]/g, '.$1').replace(/\.{2,}/g, '.');
keyArray = normalizedPath.split('.').filter(k => k !== '');
} else {
return defaultValue; // 不支持path类型
}
// 第3步:遍历路径取值
let current = object;
for (const key of keyArray) {
if (current !== null && typeof current === 'object') {
current = current[key];
} else {
return defaultValue; // 路径中断,直接返回defaultValue
}
}
// 第4步:检查结果返回逻辑
return current !== undefined ? current : defaultValue;
}
示例使用:
- 用例1:访问正确路径
const obj = { a: { b: 10 } }; const value = customGet(obj, 'a.b', 'default'); // 返回 10
- 用例2:路径未定义时回退到defaultValue
const undefinedPath = customGet(obj, 'x.y', 'fallback'); // 返回 'fallback'
- 用例3:支持数组路径 (如
.get(users, [0,'name'], '')
返回用户对象中第一个元素的名称,如果列表为空则返回’’ )。
优化考滤项:
- 此简化版代码不处理边缘案例如嵌套
undefined
或被覆盖的prototype
属性。 - 在开发调试时加强路径正则表达式以处理边界字符(如逗号、空字符串)。
- 实际项目应考虑使用TypeScript增强类型安全和错误防御。