You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从JSON数据树获取对象的函数复用问题及修复方案求解

优化方案

问题根因

原函数的核心问题是将匹配结果变量objFound定义在全局作用域,函数执行完成后该变量不会自动重置,多次调用会复用第一次执行后的残留值,导致后续查询结果异常。

方案1:封装状态变量到函数作用域(兼容原有逻辑)

将递归逻辑封装到函数内部的子函数中,每次调用外层函数都会重新初始化objFound变量,避免全局污染,逻辑和原有写法基本一致,改动成本最低:

function getObjFromValue(obj, prop, val) {
    let objFound = null;
    // 内层递归函数
    function deepSearch(currentObj) {
        Object.keys(currentObj).forEach((key) => {
            if (objFound !== null) return;
            if (key === prop && currentObj[key] === val) {
                objFound = currentObj;
                return;
            }
            if (typeof currentObj[key] === 'object' && currentObj[key] !== null) {
                deepSearch(currentObj[key]);
            }
        });
    }
    deepSearch(obj);
    return objFound;
}

注:额外加了currentObj[key] !== null的判断,避免typeof null === 'object'的JS历史问题导致报错。

方案2:无状态变量的递归实现(性能更优)

直接利用递归返回值传递匹配结果,一旦找到匹配项就逐层提前返回,不需要额外的状态变量,也不会遍历剩余节点,性能更好:

function getObjFromValue(obj, prop, val) {
    // 先判断当前层是否匹配
    if (obj.hasOwnProperty(prop) && obj[prop] === val) {
        return obj;
    }
    // 遍历所有属性递归查找
    for (const key of Object.keys(obj)) {
        const currentVal = obj[key];
        if (typeof currentVal === 'object' && currentVal !== null) {
            const matchResult = getObjFromValue(currentVal, prop, val);
            if (matchResult !== null) {
                return matchResult;
            }
        }
    }
    // 全节点未匹配返回null
    return null;
}

注:这里替换forEach为for...of循环,是因为forEach无法通过return直接终止整个循环,用for循环可以在匹配到结果后立刻终止遍历,进一步提升性能。

内容的提问来源于stack exchange,提问作者Dexter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 03:18:01