当使用点表示法访问嵌套对象时,我总是必须确保前一个对象存在,这非常令人筋疲力尽。
如果链条喜欢,我基本上想避免长时间
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) {}
有没有更好的模式呢?
当使用点表示法访问嵌套对象时,我总是必须确保前一个对象存在,这非常令人筋疲力尽。
如果链条喜欢,我基本上想避免长时间
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) {}
有没有更好的模式呢?
我认为你已经有了两个最漂亮的解决方案。
但请注意,例如,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
可能是最简单的方法
这个怎么样:
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]; }
您在问题中提到的场景也称为“可选链接”。一些语言现在已经支持它——例如 C# 有所谓的空条件运算符,它允许你短路你的表达式:
var count = customers?[0]?.Orders?.Count();
不幸的是,这个特性还没有成为当前的 JS 规范。
这将允许你写...
a?.b[3].c?.(x).d
...代替:
a == null ? undefined : a.b[3].c == null ? undefined : a.b[3].c(x).d
如果您想冒险并在这个早期阶段就已经使用它,您可以通过 babel 定位它以将其包含在您的项目中。
这是相当邪恶的,但这应该工作并且看起来不太可怕:
var i = !a ? null : !a.b ? null : !a.b.c ? null : !a.b.c.d ? a.b.c.d.e;
的原因!
是反转测试标志,以允许成功案例成为?:
. 这使我们可以像这样将它们链接在一起。
如果你想真正做到这一点,请检查运算符优先级(我做了一些非常基本的测试,我认为我做对了)。如果他们在您的代码中看到它,请期望人们会指指点点并大笑。