Monica
Monica

Reputation: 1534

What is the difference between these two JS functions?

I currently have 2 functions that do the same thing, which is a function named numbers that returns true if all the parameters that are passed are of the Number type. Otherwise, the function should return false. The function should accept any number of parameters.

So I did the following function:

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

But later on, I found this other solution.

var numbers = function() {
    return Array.prototype.filter.call(arguments, function(argument) {
      return typeof argument !== 'number';
    }).length === 0;
}

The last solution is more advanced though, but I want to know pros and cons of these 2 functions and also, which one is better? Maybe my solution will cause some errors at some point?

Upvotes: 3

Views: 114

Answers (5)

kevin ternet
kevin ternet

Reputation: 4612

They are equivalent, but I would use the some function instead of the every function for shorter notation of:

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

Upvotes: 3

Uri Goren
Uri Goren

Reputation: 13692

They are equivalent, but I would use the every function instead of the filter function for shorter notation of:

let numbers = numList => numList.every(x => typeof x === 'number');

Upvotes: 3

Jackthomson
Jackthomson

Reputation: 644

I feel a better solution to the first one could be as follows:

var numbers = numList.filter(function(a) { return a !== 'number' }

From this you can also see how I'm using the array method Filter. The second example you provide is exactly this. It is the prototype of the Array method. Prototypes are like classes that you get in other languages. Using prototype delivers better performance as it allows for quicker Object Creation thus a new Object will not have to be created each time the Object is instantiated. A good example could be as follows

const User = function(name) {
   this.name = name;
 }

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

 const user = new User('Jack')

 user.sayHello()

Using the prototype here makes sure that the sayHello method is available in the prototype chain at all times. So each time this method is instantiated Object creation is much faster as it doesn't have to recreate it each time

You should watch a guy on YouTube called FunFunFunction he may explain things a bit better than myself :)

Upvotes: 1

RobertAKARobin
RobertAKARobin

Reputation: 4258

I'd go with the first one for three reasons:

  1. Array.prototype.filter.call looks pretty ugly. for loops are much more familiar and therefore easier to read.
  2. The first function is more efficient. In addition to what deceze said, the second creates a function inside the function. This takes memory. While in most cases the difference won't be noticeable, it still is not very performant.

Edit: If you wanted to be really efficient, you could also change this:

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

...to this:

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

That's because the second argument in a for loop is evaluated before each iteration. That is: the first way, it's calculating numList.length before each iteration of the loop, whereas the second way it only does that once.

Again, in most cases this won't be a noticeable difference, but it's a way of tightening the screws a bit.

Upvotes: 3

deceze
deceze

Reputation: 522081

The first function shortcuts, i.e. it returns false as soon as it encounters a non-number. The second function always processes all inputs and decides at the end.

The first function is much more efficient.

Upvotes: 6

Related Questions