我正在尝试创建一个递归函数,该函数循环遍历一个配置对象,该对象包含必须设置的键,稍后将其与appConfig
进行比较,后者必须与unsetConfig
中的所有键(嵌套)相匹配
const _ = window._
const UNSET_CONFIG_VAR = 'UNSET'
let config = {
logging: {
hasConsole: UNSET_CONFIG_VAR,
hasSyslog: UNSET_CONFIG_VAR,
processName: UNSET_CONFIG_VAR,
inner: {
test: UNSET_CONFIG_VAR
}
}
}
const unsetConfig = _.clone(config)
function initialize (appConfig) {
const walkConfig = (currentConfigLevel, previousPaths = []) => {
for (const [key, value] of Object.entries(currentConfigLevel)) {
if (_.isObject(value)) {
previousPaths.push(key)
walkConfig(currentConfigLevel[key], previousPaths)
}
const path = previousPaths.length !== 0 ? previousPaths.join('.') : key
if (!_.get(appConfig, path)) {
throw new Error(`Config was missing: ${path}`)
}
}
}
walkConfig(unsetConfig)
}
initialize({
logging: {
hasConsole: true,
hasSyslog: true,
processName: true,
inner: {
as: true
}
}
})
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>
预期的输出将是抛出一个错误,正如您在initialize
函数中可以看到的那样,logging.inner
中缺少test
键。
但是不会抛出错误。
我现在已经在不同的设置中尝试过了,但我有点卡住了。
发布于 2018-06-01 09:13:47
如果你只想检查某个路径的值是否存在,那么你只需要使用lodash#has
。使用lodash#get
将从某个路径获取特定属性的值,但是使用这样的值来检查是否存在这样的路径是不可靠的,因为该值可能是假值。
此外,lodash#has
和lodash#get
都接受的path参数接受字符串或数组,因此实际上不需要通过分隔符将它们连接起来。事实上,当您的一个配置属性包含数组时,以这种方式连接会失败。因为数组键表示法包含在括号中,例如[0]
或[1]
。
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);
}
const { _ } = window;
const UNSET_CONFIG_VAR = 'UNSET'
let config = {
logging: {
hasConsole: UNSET_CONFIG_VAR,
hasSyslog: UNSET_CONFIG_VAR,
processName: UNSET_CONFIG_VAR,
inner: {
test: UNSET_CONFIG_VAR
}
}
}
const unsetConfig = _.cloneDeep(config); // Clone inner objects as well
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);
}
initialize({
logging: {
hasConsole: false,
hasSyslog: true,
processName: true,
inner: {
as: true
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
https://stackoverflow.com/questions/50634589
复制相似问题