Reputation: 2188
I have to get a value of a inner component. Which is better 1 or 2 when compared ONLY for performance, this method is called several times. The foo may be null depending on the runtime, but foo may have a value but bar may be null etc. It is not an error case or unexpected case that any of foo, bar, innerfoo, innerbar are null, any of them can be null at the runtime depending on the hierarchy. But innerbar can not have any value of if foo is null so there is no need to check the inner components if foo is not defined.
//1
function getInnerValue() {
if (foo && foo.bar && foo.bar.innerfoo && foo.bar.innerfoo && foo.bar.innerfoo.innerbar) {
return foo.bar.innerfoo.innerbar.x;
}
return 0;
}
//2
function getInnerValue() {
try {
return foo.bar.innerfoo.innerbar.x;
}
catch (e) {
return 0;
}
}
Upvotes: 1
Views: 550
Reputation: 15268
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())
Upvotes: 2