自从最初回答这个问题以来,我受到启发,开始开发一个图书馆来做到这一点:koalaesce。
它的工作原理类似于:
var test = {
obj: check,
oi: "5"
}
var lord = {
sol: "5"
};
var holand = {
vol: "try",
mice: lord
}
var second = {
bol: "true"
};
var check = {
fol: holand
}
function getDescendent(base, steps) {
var step = base;
for (var i = 0; i < steps.length; ++i) {
if (step.hasOwnProperty(steps[i])) {
step = step[steps[i]];
} else {
throw new Error("Missing link at " + steps[i]);
}
}
return step;
}
document.write(getDescendent(check, ["fol", "mice", "sol"]));
try {
document.write(getDescendent(check, ["fol", "tofu", "sol"]));
} catch (e) {
document.write(e);
}
这里的算法从base 对象开始向下运行,遍历代表每个步骤的属性名称的字符串数组。它检查以确保当前对象具有其自己的属性(不是继承的)并具有适当的名称,然后向下移动到该级别。如果对象没有,它会抛出缺少的名称。
在很多情况下,您可能希望删除 hasOwnProperty 检查,因为继承/原型属性和方法可能很有用(并且不会造成任何伤害)。在您的情况下,对于简单的对象,行为不会改变。在大多数情况下,不检查将允许您访问更多属性。
对于更聪明的 ES6 解决方案,您还可以使用 reduce 和:
let test = {
obj: check,
oi: "5"
}
let lord = {
sol: "5"
};
let holand = {
vol: "try",
mice: lord
}
let second = {
bol: "true"
};
let check = {
fol: holand
}
function getDescendent(base, ...steps) {
return steps.reduce((prev, cur) => {
if (prev && prev.hasOwnProperty(cur)) {
return prev[cur];
} else {
throw new Error("Missing link at " + cur);
}
}, base);
}
document.write(getDescendent(check, "fol", "mice", "sol"));
document.write(getDescendent(check, "fol", "tofu", "sol"));