这是另一种可能性。
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));
开启jsfiddle
更新:这比reduce 更加跨浏览器。如果我们希望对数据进行更多检查,我们也可以对此进行改进。
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, {}));
我们可以在不检查的情况下进行比较
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, {}));
开启jsfiddle
引入的这些额外检查对性能有何影响?
让我们看看,jsperf
请随意将其他解决方案添加到性能测试中。 - 我添加了其他解决方案。
无论如何,我会避免在循环通过arguments 对象时使用for..in(以避免循环通过可能已附加到arguments 的任何方法)并且会选择任何其他常用的Array 循环方法:for、while、forEach 或 reduce
查看相关性:Why is using “for…in” with array iteration such a bad idea?