是否有一种本机方式来解析JavaScript对象?
假设我想访问是否有一种本机方式来解析JavaScript对象?,javascript,Javascript,假设我想访问a.b.c.d,我不确定b或c是否存在。 “天真”检查将是: if (a.b && a.b.c && a.b.c.d == 5) doSomething(a.b.c.d); 我仔细考虑了这一点,并编写了这个函数来改进这一点: Object.prototype.parse = function (keys, def) { return keys.split('.').reduce(function (prev, curr) { if (pr
a.b.c.d
,我不确定b
或c
是否存在。
“天真”检查将是:
if (a.b && a.b.c && a.b.c.d == 5) doSomething(a.b.c.d);
我仔细考虑了这一点,并编写了这个函数来改进这一点:
Object.prototype.parse = function (keys, def) {
return keys.split('.').reduce(function (prev, curr) {
if (prev) {
return prev[curr];
}
}, this) || def;
};
你可以这样使用它:
var a = {
b: {
c: {
d: 5
}
}
};
console.log(a.parse('b.c.d', 3)); // If b, c or d are undefined return 3
但是我想知道我是否缺少了一种更好的、自然的方法来实现这一点,而不是将此功能添加到项目中
谢谢 我想我有另一个解决这个问题的方法,我花了几分钟的时间试图做到这一点。如果您正在处理窗口范围,则可以使用my函数查看对象是否存在或返回默认值
function parseObj(obj){
try{
return eval(obj);
}catch(e){
return null;
}
}
用法
我不知道这是否是你想要的,但我相信它会给你另一个想法。干得不错。唯一的原生方式是,但我不推荐它,因为它可以用于执行任意代码。这可能没问题,但如果“a.b.c.d”样式的字符串来自不受信任的用户,则不会。我会坚持你的手工解决方案或使用
eval()将抛出与未定义b或c时本机等效项相同的错误,因此您需要使用try{}catch{}块进行包装。可能不是您想要的,但可能尽可能接近“本机”(您提供的split/reduce代码段的更紧凑版本):
如果您希望使用类似于
“a.b.c.d”
的字符串的解决方案,则需要使用eval
(不重新编码),或者对象a
需要是全局的(也不推荐)或者该对象需要是另一个对象的属性,这几乎不会弄巧成拙。您也可以在其周围放置一个异常处理程序,然后访问var x=a.b.c.d
。它要么成功,抛出异常,要么返回undefined
(如果只缺少d
)。有一个库需要这样做。@jfriend00 try..catch解决方案速度明显较慢,因为它禁用了解释器优化。您的问题中有这样的要求吗?你要的是一种土生土长的方法。我提供了一个。然后,你去接受一个需要尝试的答案。我很困惑。性能取决于浏览器。try/catch解决方案(您不抛出异常)在Firefox中速度快得多,在其他浏览器中速度慢得多。我认为他正在试图解决“未捕获引用错误:未定义”错误。请投票人解释一下。谢谢。亲爱的投票人,我知道你可能不喜欢eval-我不喜欢,但这完全回答了原来的问题-这是一个真实的答案,但我们有一些有趣的投票人没有任何理由。被投票人否决一个真实的答案很有趣。
alert(parseObj("a.b.c.d"));
var a = {
b: {
c: {
d: 5
}
}
};
console.log(eval("a.b.c.d"));
var a = {b:{c:{d:5}}};
("b.c.d").split(".").reduce(function(p,c){return p && p[c];},a); //5
("b.c.e").split(".").reduce(function(p,c){return p && p[c];},a); //undefined