26

当使用点表示法访问嵌套对象时,我总是必须确保前一个对象存在,这非常令人筋疲力尽。

如果链条喜欢,我基本上想避免长时间

if (a && a.b && a.b.c && a.b.c[0] ... ) { v = a.b.c[0]; }

我唯一能想到的另一件事是通过使用 try catch。

var v; try { v = a.b.c[0].d.e; } catch (e) {}

有没有更好的模式呢?

4

4 回答 4

2

我认为你已经有了两个最漂亮的解决方案。

但请注意,例如,obj.obj.string.length如果string === "". 由于空字符串是错误的,它会绊倒&&守卫。

但是说到字符串,你可以这样做:

function getNestedProperty(obj, propChain) {
    var props = propChain.slice(0), prop = props.shift();
    if(typeof obj[prop] !== "undefined") {
        if(props.length) {
            return getNestedProperty(obj[prop], props);
        } else {
            return obj[prop];
        }
    }
}

var v = getNestedProperty(a, ["b", "c", 0, "d", "e"]);

是的...不太漂亮:P

我想说,在提出的解决方案中,try...catch可能是最简单的方法

于 2013-11-05T18:45:56.517 回答
0

这个怎么样:

var hasProperty = function (object, property) {

    var properties = property.split('.'),
        temp = object;

    while (temp && properties.length) {
        temp = temp[properties.shift()];
    }

    return !!temp;
};

然后像这样使用它:

if (a && hasProperty(a, 'b.c.0' ) { v = a.b.c[0]; }
于 2013-11-05T19:49:14.950 回答
0

您在问题中提到的场景也称为“可选链接”。一些语言现在已经支持它——例如 C# 有所谓的空条件运算符,它允许你短路你的表达式:

var count = customers?[0]?.Orders?.Count();

不幸的是,这个特性还没有成为当前的 JS 规范。

可以在此处跟踪“可选链接”的开放阶段 1提案。

这将允许你写...

a?.b[3].c?.(x).d

...代替:

a == null ? undefined : a.b[3].c == null ? undefined : a.b[3].c(x).d

如果您想冒险并在这个早期阶段就已经使用它,您可以通过 babel 定位它以将其包含在您的项目中。

于 2019-02-10T18:52:46.307 回答
-1

这是相当邪恶的,但这应该工作并且看起来不太可怕:

var i = !a ? null : !a.b ? null : !a.b.c ? null : !a.b.c.d ? a.b.c.d.e;

的原因!是反转测试标志,以允许成功案例成为?:. 这使我们可以像这样将它们链接在一起。

如果你想真正做到这一点,请检查运算符优先级(我做了一些非常基本的测试,我认为我做对了)。如果他们在您的代码中看到它,请期望人们会指指点点并大笑。

于 2013-11-05T18:20:40.133 回答