安全访问 Javascript 嵌套对象

IT技术 javascript node.js
2021-02-02 03:47:17

我有基于 json 的数据结构,其中的对象包含嵌套对象。为了访问特定的数据元素,我将对象属性的引用链接在一起。例如:

var a = b.c.d;

如果 b 或 bc 未定义,这将失败并显示错误。但是,如果它存在,我想获取一个值,否则只是未定义。在不必检查链中的每个值是否存在的情况下,执行此操作的最佳方法是什么?

我想尽可能保持这种方法的通用性,这样我就不必添加大量的辅助方法,例如:

var a = b.getD();

或者

var a = helpers.getDFromB(b);

我还想尽量避免使用 try/catch 结构,因为这不是错误,因此使用 try/catch 似乎放错了地方。这合理吗?

有任何想法吗?

6个回答

标准方法:

var a = b && b.c && b.c.d && b.c.d.e;

非常快但不太优雅(尤其是对于较长的属性名称)。

使用函数遍历 JavaScipt 对象属性既不高效也不优雅。

试试这个:

try { var a = b.c.d.e; } catch(e){}

如果您确定a以前没有使用过或

try { var a = b.c.d.e; } catch(e){ a = undefined; }

以防您之前分配过它。

这可能比第一个选项更快。

ECMAScript2020和 Node v14 具有可选的链接运算符(我已经看到它也称为安全导航运算符),这将允许您的示例编写为:

var a = b?.c?.d;

来自MDN 文档

可选链运算符 (?.) 允许读取位于连接对象链深处的属性值,而无需明确验证链中的每个引用是否有效。这 ?。运算符的功能类似于 。链接运算符,除了如果引用为空(空或未定义)时不会导致错误,表达式会短路返回值未定义。当与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。

您可以创建一个通用方法来访问基于属性名称数组的元素,该数组被解释为通过属性的路径:

function getValue(data, path) {
    var i, len = path.length;
    for (i = 0; typeof data === 'object' && i < len; ++i) {
        data = data[path[i]];
    }
    return data;
}

然后你可以调用它:

var a = getValue(b, ["c", "d"]);
@Hubris - 属性名称始终是字符串。点符号被认为是“语法糖”(如果属性名称是保留字或不是有效的 JS 标识符,它甚至不起作用)。
2021-03-17 03:47:17
@Hubris - 请注意 Chris 的评论;它链接到一个使用相同想法但更高级的答案。它允许您传递像“cd”这样的单个字符串,然后按照指示的路径为您解析它。
2021-03-22 03:47:17
好吧,我就是这么想的。惊人的。谢谢 :)
2021-03-28 03:47:17
鉴于 ab === a['b'] 我认为在 JS 中使用字符串来引用对象被认为是最佳实践?
2021-04-12 03:47:17

这是一个老问题,现在有了 es6 特性,这个问题可以更容易地解决。

const idx = (p, o) => p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o);

感谢@sharifsbeat 提供此解决方案

可能很简单:

let a = { a1: 11, b1: 12, c1: { d1: 13, e1: { g1: 14 }}}
console.log((a || {}).a2); => undefined
console.log(((a || {}).c1 || {}).d1) => 13

等等。