Anything with a try catch that ever gets triggered will incur a large performance hit.
Personally I don't find the long chain of truthy checks any less readable than a try catch block. Just longer, ugly and verbose. But really, would anyone ever have trouble reading that (or editing it)? Or better put, would you even need to read it to understand what it is doing?
In fact if anything the try catch block feels like more of a hack. I still have to think about why I'm trying to catch an exception, and it's still ugly.
In any case, we now have optional chaining, so the above doesn't even really matter anymore. I'd go with something like return x?.y?.z?.a?.b?.c?.d||0
.
You can of course go with guard functions, as you've probably already noticed reading the thread you've linked. Something like lodash _.get
or your own guard(a,'b','c','d').
optional chaining browser compatibility
Babel transpiled output of optional chaining
x?.y
will immediately return undefined
if x is null or undefined
Browser compatibility is relatively new. Check table of compatibility. You should add Babel transpilation to your pipeline.
optional chaining without transpilation:
foo = {}
function fn() {
if (foo?.bar?.innerfoo?.innerbar)
return foo.bar.innerfoo.innerbar.x
return 0
}
console.log(fn())
foo = {bar: { innerfoo: { innerbar: { x: 5 }}}}
console.log(fn())
transpiled code:
foo = {}
function fn() {
var _foo, _foo$bar, _foo$bar$innerfoo;
if ((_foo = foo) === null || _foo === void 0 ? void 0 : (_foo$bar = _foo.bar) === null || _foo$bar === void 0 ? void 0 : (_foo$bar$innerfoo = _foo$bar.innerfoo) === null || _foo$bar$innerfoo === void 0 ? void 0 : _foo$bar$innerfoo.innerbar) return foo.bar.innerfoo.innerbar.x;
return 0;
}
console.log(fn())
foo = {bar: { innerfoo: { innerbar: { x: 5 }}}}
console.log(fn())