这两个JS函数有什么区别?

3

我目前有两个函数,这两个函数都是判断传递参数是否全部为数字类型的功能。其中一个名为"numbers"的函数,如果参数全部为数字类型,则返回true;否则,函数应该返回false。该函数可以接受任意数量的参数。

因此,我创建了以下函数:

var numbers = function(numList) {
    for(var i = 0; i < numList.length; i++) {
        if ( typeof numList[i] !== 'number' ) {
           return false;
        }
    }  
    return true;
}

但后来,我发现另一个解决方案。
var numbers = function() {
    return Array.prototype.filter.call(arguments, function(argument) {
      return typeof argument !== 'number';
    }).length === 0;
}

虽然最后一种解决方案更高级,但我想知道这两个函数的优缺点,并且,哪一个更好?也许我的解决方案在某些时候会出现错误?


1
调试第一个对我来说更容易,因为作用域始终保持一致。虽然在此示例中出现问题不会导致作用域问题,但在更复杂的示例中可能会遇到这种情况。 - jusopi
1
它们似乎做着相同的事情,只是语法不同,而且两者都没有比另一个更好。 - adeneo
对我来说也是如此。但我正在尝试学习更高级的JavaScript。第一个是我的解决方案。第二个是更高级的解决方案,实际上花了我4个小时才理解。 - Monica
1
请记住:编写能够运行的代码并不是太难。而编写易于阅读的代码则更加困难,也更加重要。 - RobertAKARobin
5个回答

6
第一个函数是“快捷方式”,即只要遇到非数字就返回false。第二个函数总是处理所有的输入,并在最后决定。
第一个函数更加高效。

3
它们是等价的,但我建议使用 every 函数代替 filter 函数,以便更简洁地表示:
let numbers = numList => numList.every(x => typeof x === 'number');

实际上,every函数在ECMAScript 5.1(ECMA-262)规范中定义,箭头符号是ES6中新增的。 - Uri Goren

3
我会选择第一个原因,有以下三个方面的考虑:
  1. Array.prototype.filter.call 看起来很丑陋,而 for 循环更加常见,因此更容易阅读。
  2. 第一个函数更高效。除了 deceze 提到的之外,第二个函数在函数内创建了一个函数,这会占用内存。虽然在大多数情况下差异不会太明显,但仍然不够高效。

编辑:如果你想要真正高效,你还可以改变这个:

for(var i = 0; i < numList.length; i++)

...变成这样:

for(var i = 0, l = numList.length; i < l; i++)

这是因为在 for 循环中的第二个参数在每次迭代之前都会被计算。也就是说:第一种方法会在每次循环迭代之前计算 numList.length ,而第二种方法只会计算一次。

同样,在大多数情况下,这不会有太大的区别,但这是一种微调的方式。


3

它们是等效的,但我会使用some函数代替every函数来缩短以下符号的表示:

var numbers = numList => !numList.some(x => typeof x !== 'number');

虽然看起来并不更短 :P - Walfrat
既不更短也不更快,只是另一种解决方案。 - kevin ternet
but I would use the some function instead of the every function for shorter notation of i was just being a bit pedantic since you have more character, but you could replace your ternary expression by a simple ! - Walfrat
是的,Walfrat,我刚刚重新编辑了。谢谢你的建议。 - kevin ternet

1
我认为第一个问题的更好解决方案如下所示:
``` var numbers = numList.filter(function(a) { return a !== 'number' } ```
从这里可以看出我是如何使用数组方法`Filter`。你提供的第二个例子就是这样。它是数组方法的原型。原型类似于其他语言中的类。使用原型可以提高性能,因为它允许更快的对象创建,因此每次实例化对象时不必创建新对象。一个很好的例子可能如下:
const User = function(name) {
   this.name = name;
 }

 User.prototype.sayHello = function() {
   console.log('Hello ' + this.name)
 }

 const user = new User('Jack')

 user.sayHello()

使用这里的原型可以确保sayHello方法始终在原型链中可用。因此,每次实例化对象时,对象创建速度更快,因为它不必每次重新创建它。
你应该在YouTube上观看一个叫做FunFunFunction的人,他可能会比我解释得更好 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接