Here is another possibility.
function add() {
var numbers = [].slice.call(arguments),
sum = 0;
do {
sum += numbers.shift();
} while (isFinite(sum) && numbers.length);
return +sum;
}
console.log(add(1, 2, 3, 4, 5));
On jsfiddle
Update: This is more cross browser than reduce
. We can also improve on this if we wish to do a little more checking of the data.
function add1() {
var numbers = [].slice.call(arguments),
sum = 0,
x;
do {
x = numbers.shift();
sum += (typeof x === "number" ? x : NaN);
} while (isFinite(sum) && numbers.length);
return +sum;
}
console.log("add1", add1(1, 2, 3, 4, 5));
console.log("add1", add1(1, 2, 3, 4, 5, ""));
console.log("add1", add1(1, 2, 3, 4, 5, "0xA"));
console.log("add1", add1(1, 2, 3, 4, 5, NaN));
console.log("add1", add1(1, 2, 3, 4, 5, Infinity));
console.log("add1", add1(1, 2, 3, 4, 5, -Infinity));
console.log("add1", add1(1, 2, 3, 4, 5, true));
console.log("add1", add1(1, 2, 3, 4, 5, false));
console.log("add1", add1(1, 2, 3, 4, 5, null));
console.log("add1", add1(1, 2, 3, 4, 5, undefined));
console.log("add1", add1(1, 2, 3, 4, 5, []));
console.log("add1", add1(1, 2, 3, 4, 5, {}));
And we can compare that with no checking
function add2() {
return [].reduce.call(arguments, function (a, b) {
return a + b;
});
}
console.log("add1", add2(1, 2, 3, 4, 5));
console.log("add1", add2(1, 2, 3, 4, 5, ""));
console.log("add2", add2(1, 2, 3, 4, 5, "0xA"));
console.log("add2", add2(1, 2, 3, 4, 5, NaN));
console.log("add2", add2(1, 2, 3, 4, 5, Infinity));
console.log("add2", add2(1, 2, 3, 4, 5, -Infinity));
console.log("add2", add2(1, 2, 3, 4, 5, true));
console.log("add2", add2(1, 2, 3, 4, 5, false));
console.log("add2", add2(1, 2, 3, 4, 5, null));
console.log("add2", add2(1, 2, 3, 4, 5, undefined));
console.log("add2", add2(1, 2, 3, 4, 5, []));
console.log("add2", add2(1, 2, 3, 4, 5, {}));
On jsfiddle
And how is the performance affected by these extra checks that were introduced?
Let's see, jsperf
Feel free to add the other solutions to the performance test. - I added the others.
Anyway, I would avoid using for..in
when looping through an arguments
object (to avoid looping through any methods that may have been attached to arguments
) and would choose any of the other usual Array
looping methods: for
, while
, forEach
or reduce
See relevance: Why is using “for…in” with array iteration such a bad idea?