有没有一种原生的方法来解析JavaScript对象?

3

假设我要访问a.b.c.d,但我不确定bc是否存在。最简单的检查方法是:

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

但我在想是否有更好的本地方法来实现这一点,而不必将此函数添加到项目中。

谢谢!


2
你也可以在其周围放置一个异常处理程序,只需访问 var x = a.b.c.d。它将成功、抛出异常或返回 undefined(如果仅丢失了 d)。 - jfriend00
2
有一个叫做dotty的库可以用来处理这种事情。 - Paul
性能取决于浏览器。在Firefox中,不抛出异常的try/catch解决方案速度更快,在其他浏览器中速度较慢。 - jfriend00
@jfriend00 对不起让你感到困惑。我选择那个答案是因为它提供了关于eval的见解,并建议我使用dotty,这是我从未听说过的,或者使用我的解决方案,考虑到缺乏本地解决方案,这是最好的选择。 - Ben
在SO上有数十个与此主题相关的答案,既评估形式为a.b.c的属性字符串,又进行所谓的“存在性检查”a && a.b && a.b.c。搜索它们。 - user663031
显示剩余3条评论
3个回答

1
也许不完全符合你的要求,但可能是最接近“本地”的方式(一种稍微更紧凑的split/reduce片段版本,与你提供的相似):
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

如果你希望解决类似于 "a.b.c.d" 的字符串问题,那么你需要使用 eval(不推荐)或者对象 a 必须是全局的(也不推荐),或者该对象必须是另一个对象的属性,这有点自我矛盾。

-2

我认为我有另一个解决这个问题的方法,我试图实现这个方法已经几分钟了。如果你正在处理窗口作用域,你可以使用我的函数来查看对象是否存在或返回默认值。

function parseObj(obj){
    try{
        return eval(obj);
    }catch(e){
        return null;
    }
}

用法

alert(parseObj("a.b.c.d"));

我不确定这是否是您正在寻找的内容,但我相信它会给您另一个想法。祝您工作愉快。


-2

唯一的本地方式是eval,但我不建议使用它来执行任意代码。这可能没问题,但如果你的“a.b.c.d”样式字符串来自不受信任的用户,则不行。我建议使用你自己编写的解决方案或使用dotty

var a = {
  b: {
    c: {
      d: 5
    }
  }
};
console.log(eval("a.b.c.d"));

如果b或c未定义,eval()将抛出与本机等效项相同的错误,因此您需要使用try {} catch {}块进行包装。


我认为他试图解决“Uncaught ReferenceError: a is not defined”错误。 - Ahmet Can Güven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接