如何用递归实现JavaScript可选链函数?递归性能更优吗?
递归实现对象路径取值函数及性能对比
递归实现代码
我们可以先把路径字符串拆分为属性数组,再通过递归逐层访问对象属性,代码实现如下:
const obj = {a: {b: {c: {d: 'Hello'}}}} function optionalChaining(obj, path) { // 将路径按点分割为属性数组 const props = path.split('.'); // 递归辅助函数,负责逐层遍历对象 function traverse(currentObj, propList) { // 边界判断:当前值不是对象/为null,直接返回undefined if (currentObj == null || typeof currentObj !== 'object') { return undefined; } // 属性列表为空时,返回当前对象(路径遍历完成) if (propList.length === 0) { return currentObj; } // 取出第一个属性,递归遍历剩余路径 const [firstProp, ...restProps] = propList; return traverse(currentObj[firstProp], restProps); } return traverse(obj, props); }
测试结果完全符合预期:
optionalChaining(obj, "a.b.c"); // { d: 'Hello' } optionalChaining(obj, "a.b.c.d"); // Hello optionalChaining(obj, "a.b.c.d.e"); // undefined optionalChaining(obj, "b.d.a"); // undefined
递归 vs Reduce 的性能对比
从性能层面来看,Reduce 通常比递归略快,核心原因如下:
- 递归需要不断创建新的函数调用栈,每一层递归都存在额外的调用开销;而 Reduce 是迭代式处理,没有函数调用栈的额外消耗。
- 虽然现代 JS 引擎有尾递归优化,但上述递归实现不属于严格意义上的尾递归场景(部分引擎对尾递归的支持也有限),无法完全消除栈开销。
- 极端场景下(比如路径包含几十层属性),递归可能触发栈溢出错误,而 Reduce 作为迭代方式不会出现这个问题。
不过在日常开发的绝大多数场景中,两者的性能差异几乎可以忽略。选择哪种实现,主要看代码可读性和团队习惯:递归写法更贴合“逐层深入”的思维逻辑,Reduce 写法则更简洁紧凑。
内容的提问来源于stack exchange,提问作者Will Black
相关产品推荐
相关产品推荐

