Javascript递归嵌套比较循环

Javascript递归嵌套比较循环,javascript,loops,object,recursion,lodash,Javascript,Loops,Object,Recursion,Lodash,我试图创建一个递归函数,该函数循环通过一个config对象,该对象包含必须设置的键,这将与稍后的appConfig进行比较,后者必须匹配嵌套在config中的所有键 常数=窗口_ const UNSET_CONFIG_VAR='UNSET' 让配置={ 日志记录:{ hasConsole:UNSET_CONFIG_VAR, hasSyslog:UNSET_CONFIG_VAR, processName:UNSET_CONFIG_VAR, 内部:{ 测试:取消设置配置变量 } } } const

我试图创建一个递归函数,该函数循环通过一个config对象,该对象包含必须设置的键,这将与稍后的appConfig进行比较,后者必须匹配嵌套在config中的所有键

常数=窗口_ const UNSET_CONFIG_VAR='UNSET' 让配置={ 日志记录:{ hasConsole:UNSET_CONFIG_VAR, hasSyslog:UNSET_CONFIG_VAR, processName:UNSET_CONFIG_VAR, 内部:{ 测试:取消设置配置变量 } } } const unsetConfig=\ uu0.cloneconfig 函数初始化appConfig{ 常量walkConfig=currentConfigLevel,以前的路径=[]=>{ 对于Object.entriescurrentConfigLevel的常量[key,value]{ 如果u0.isObjectvalue{ 上一个按钮 walkConfigcurrentConfigLevel[键],以前的路径 } 常量路径=previousPaths.length!==0?previousPaths.join'.':键 if!\uux.getappConfig,路径{ 抛出新错误`缺少配置:${path}` } } } WalkConfig配置 } 初始化{ 日志记录:{ 哈斯:是的, 哈西斯洛:没错, processName:true, 内部:{ as:是的 } } }
如果只希望检查某个路径中是否存在值,则只需使用。使用lodashget将从特定路径获取特定属性的值,但使用此类值检查此类路径的存在性是不可靠的,因为该值可能是虚假值

此外,lodashhas和都接受的path参数都接受字符串或数组,因此实际上不需要从分隔符连接它们。事实上,当您的一个config属性包含数组时,以这种方式连接该属性将失败。因为数组键表示法包含在括号中,例如[0]或[1]

常数{{}=window; const UNSET_CONFIG_VAR='UNSET' 让配置={ 日志记录:{ hasConsole:UNSET_CONFIG_VAR, hasSyslog:UNSET_CONFIG_VAR, processName:UNSET_CONFIG_VAR, 内部:{ 测试:取消设置配置变量 } } } const unsetConfig=\uu0.cloneDeepconfig;//同时克隆内部对象 函数初始化AppConfig{ const walkConfig=config,路径=[]=>{ Object.entriesconfig.forEach[键,值]=>{ 让$path=path.concatkey; 如果!\uux.hasappConfig,$path{ 抛出新错误`缺少配置:${$path.join'.}`; } if.isObjectvalue{ walkConfigvalue$路径; } }; }; WalkConfig配置; } 初始化{ 日志记录:{ 哈斯:错, 哈西斯洛:没错, processName:true, 内部:{ as:是的 } } }
使用调试器并逐步完成代码。阅读了解如何调试代码的提示。我建议您学习如何在Google、Firefox或您使用的任何浏览器中使用开发人员工具。错误:缺少配置:logging.hassConsole.hasSyslog-fail?我还将交换if..isObjectvalue{和if!u.hasappConfig$路径的顺序{-要获得正确的错误消息:我相当确信错误消息是正确的,正如OP所提到的:预期的输出将是抛出错误,正如您在初始化函数中看到的,logging.inner.yes中缺少测试键,但请尝试将inner:{as:true}或甚至inner:{test:true}而不是inner:{as:true}在传递给初始化的对象中……当然,错误在某种程度上是正确的,但事实是,内部是不存在的属性。我认为我们之间的关系很好地回答了这个问题:p我将删除我的答案,它基本上是多余的:p
function initialize(appConfig) {

  const walkConfig = (config, paths = []) => {
    Object.entries(config).forEach(([key, value]) => {
      let $paths = paths.concat(key);

      if(!_.has(appConfig, $paths)) {
        throw new Error(`Config was missing: ${$paths.join('.')}`);
      }

      if(_.isObject(value)) {
        walkConfig(value, $paths);
      }
    });
  };

  walkConfig(unsetConfig);

}