Would it be faster to just put code inside a try-catch block instead of performing various error checks?
For example..
function getProjectTask(projec
Sure, it makes for more compact code, but it reduces your debug ability and makes adding graceful error-recovery, or useful error messages much, much, harder.
Performance wise try-catch is 20-50% slower than if checks (https://jsperf.com/throw-catch-vs-if-check/1).
So, For rare usage, doesn't make much difference. For heavy usage, it might make some difference.
However, I feel it's bad practice to use try-catch, if it can be done by if checks except if it greatly reduces readability.
Placing dogma aside and not being satisfied with the answers here at the moment...
If your code rarely throws exceptions, placing a try-catch around the offender performs well because there is no additional overhead in catching the exception or preventing it.
If the code commonly throws exceptions based on unpredictable data or some scenario similar to that, placing a guard method increases performance considerably, up to 20 times if exceptions occur often.
If I were to advise an approach, use simple guard operators when possible if there isn't deep nesting. In cases of deeper nesting, use a guard method that can traverse through as needed.
Here's some testing of my own that I based this off of.
http://jsfiddle.net/92cp97pc/6/
Scenarios are comparing the following but in loops:
var a;
// scenario 1 (always throws/catches)
try { a.b.c.d; }
catch(ex) { }
// scenario 2 (about 20 times faster than scenario 1)
guard(a, 'b', 'c', 'd');
// now no exceptions will occur
a = { b: { c: { d: true } } };
// scenario 3 (too fast to measure)
try { a.b.c.d; }
catch(ex) { }
// scenario 4 (.04 times slower than scenario 3)
guard(a, 'b', 'c', 'd');
Keep in mind that this varies based on browsers as well but overall I have not read anything about significant performance penalties for using a try/catch block. But it's not exactly a good practice to get into using them because you are not able to tell why a problem failed.
Here is an interesting slide show of some javascript performance considerations. On slide 76 they cover try/catch blocks and the performance impact. http://www.slideshare.net/madrobby/extreme-javascript-performance
Why not have a fact basis for the argument? The following code demonstrates the performance impact:
var Speedy = function() {
this.init();
};
Speedy.prototype = {
init: function() {
var i, t1;
this.sumWith = 0;
this.sumWithout = 0;
this.countWith = 0;
this.countWithout = 0;
for (i = 0; i < 5; i++) {
t1 = this.getTime();
console.log("Using Try/Catch, Trial #" + (i + 1) );
console.log("started " + t1 );
this.goTry(t1);
this.countWith++;
}
for (i = 0; i < 5; i++) {
t1 = this.getTime();
console.log("W/out Try/Catch, Trial #" + (i + 1) );
console.log("started :" + t1 );
this.goAlone(t1);
this.countWithout++;
}
for (i = 5; i < 10; i++) {
t1 = this.getTime();
console.log("Using Try/Catch, Trial #" + (i + 1) );
console.log("started :" + t1);
this.goTry(t1);
this.countWith++;
}
for (i = 5; i < 10; i++) {
t1 = this.getTime();
console.log("W/out Try/Catch, Trial #" + (i + 1) );
console.log("started :" + t1);
this.goAlone(t1);
this.countWithout++;
}
console.log("---------------------------------------");
console.log("Average time (ms) USING Try/Catch: " + this.sumWith / this.countWith + " ms");
console.log("Average time (ms) W/OUT Try/Catch: " + this.sumWithout / this.countWithout + " ms");
console.log("---------------------------------------");
},
getTime: function() {
return new Date();
},
done: function(t1, wasTry) {
var t2 = this.getTime();
var td = t2 - t1;
console.log("ended.....: " + t2);
console.log("diff......: " + td);
if (wasTry) {
this.sumWith += td;
}
else {
this.sumWithout += td;
}
},
goTry: function(t1) {
try {
var counter = 0;
for (var i = 0; i < 999999; i++) {
counter++;
}
this.done(t1, true);
}
catch (err) {
console.error(err);
}
},
goAlone: function(t1) {
var counter = 0;
for (var i = 0; i < 999999; i++) {
counter++;
}
this.done(t1, false);
}
};
var s = new Speedy();
This JSFiddle will show you the output in firebug lite's console: http://jsfiddle.net/Mct5N/
Depends on the situation. As galambalazs mentions readability is important. Consider:
function getCustomer (id) {
if (typeof data!='undefined' && data.stores && data.stores.customers
&& typeof data.stores.customers.getById=='function') {
return data.stores.customers.getById(id);
} else {
return null;
}
}
compared to:
function getCustomer (id) {
try {return data.stores.customers.getById(id);} catch (e) { return null; }
}
I'd say the second is much more readable. You tend to get data back like this from things like google's apis or twitter's feeds (usually not with deeply nested methods though, that's just here for demonstration).
Of course, performance is also important, but these days javascript engines are fast enough that nobody's likely to notice a difference, unless you're going to call getCustomer every ten milliseconds or something.