可用reduce配合split('.')安全读取嵌套配置:路径转键数组后逐层访问,每步检查对象存在性,缺失则返回undefined或默认值;支持点号、方括号语法及柯里化调用。

可以用 reduce 配合 split('.') 把路径字符串转为键数组,再逐层访问对象属性,安全地读取嵌套配置。
核心思路:把路径拆解为键序列,用 reduce 逐级取值
例如路径 "server.host" → 拆成 ['server', 'host'] → 从配置对象开始,依次取 obj['server']['host']。关键在于每一步都要检查当前层级是否存在且为对象,避免 Cannot read property 'xxx' of undefined 错误。
- 起始值设为整个配置对象
- 每轮 reduce 中,用当前键访问上一轮结果
- 若中途遇到
undefined、null或非对象值,直接返回undefined(或按需返回默认值)
基础实现(带安全防护)
以下函数支持点号路径,自动处理中间层级缺失:
function get(config, path, defaultValue) {
return path.split('.').reduce((obj, key) => {
return obj && typeof obj === 'object' ? obj[key] : undefined;
}, config) ?? defaultValue;
}
用法示例:
const config = {
server: {
host: 'localhost',
port: 8080,
ssl: { enabled: true }
},
features: ['auth', 'logging']
};
get(config, 'server.host'); // 'localhost'
get(config, 'server.ssl.enabled'); // true
get(config, 'database.url'); // undefined
get(config, 'database.url', 'sqlite://local.db'); // 'sqlite://local.db'
支持方括号语法和数组索引(进阶版)
如果路径含数组访问(如 "items[0].name"),需先解析路径字符串。可用正则分词,提取所有键和索引:
function parsePath(path) {
return path.match(/[^.[\]]+/g) || [];
}
function get(config, path, defaultValue) {
const keys = parsePath(path);
return keys.reduce((obj, key) => {
return obj && typeof obj === 'object' ? obj[key] : undefined;
}, config) ?? defaultValue;
}
这样就能支持:get(config, 'features[0]') → 'auth',get(config, 'server.ssl') → { enabled: true }。
可选:支持函数式组合与柯里化
把 get 变成柯里化函数,便于复用和管道操作:
const get = (path) => (config, defaultValue) =>
path.split('.').reduce((obj, key) =>
obj && typeof obj === 'object' ? obj[key] : undefined,
config
) ?? defaultValue;
// 使用
const getHost = get('server.host');
getHost(config); // 'localhost'
// 配合其他函数链式调用
const hostUpper = compose(
(s) => s?.toUpperCase(),
get('server.host')
);
hostUpper(config); // 'LOCALHOST'
不复杂但容易忽略的是空路径、连续点号或开头/结尾点号等边界情况;实际项目中建议加一层 path.trim().replace(/\.{2,}/g, '.') 预处理,再校验是否为空字符串。

















