This is trouble:
if (foo.bar.baz.woo.yay === 8675309) {
doStuff();
}
... because foo or foo.bar or foo.bar.baz or foo.bar.baz.woo might not be there, and you'll get this:
ReferenceError: foo.bar is not defined
Instead we engage in calisthenics like this:
if (foo) {
if (foo.bar) {
if (foo.bar.baz) {
if (foo.bar.baz.woo) {
if (foo.bar.baz.woo.yay === 8675309) {
doStuff();
}
}
}
}
}
Thanks to Oliver Steele's 2007 post Monads on the Cheap I: The Maybe Monad we can try this:
if (((((foo || {}).bar || {}).baz || {}).woo || {}).yay === 8675309) {
doStuff();
}
... and as long as base object foo is defined, we'll get undefined if the chain breaks at any point.
Dealing with API returns from potentially-untrustworthy endpoints. Like this:
const renderListLengthThreeOrGreater = output => {
if (output.data) {
if (output.data.stuff) {
if (output.data.stuff.list) {
if (output.data.stuff.list.length > 2) {
output.data.stuff.list.filter(item => {
doStuffWith(item);
});
}
}
}
}
}
... which looks better like this, at least to me:
const renderListLengthThreeOrGreater = output => {
if (((output.data || {}).stuff || {}).list.length > 2) {
output.data.stuff.list.filter(item => {
doStuffWith(item);
});
}
}
Here are some tests on JSBEN.CH, which seem to indicate it's faster.