简体   繁体   中英

Javascript: please help me understand this function

I've been trying to understand this function for quite a while, but it just doesn't make sense to me. The goal of the function is to remove any numbers within the array of arguments that match the other argument numbers.

Why is it necessary to slice the array for the function to work?

Is args.splice(0,1) redundant? I removed it and nothing changed.

It seems like the filter function does the bulk of the work, but I don't see how it actually filters for the numbers...

function destroyer(arr) {
  var args = Array.prototype.slice.call(arguments);
  args.splice(0, 1);
  return arr.filter(function(element) {
    return args.indexOf(element) === -1;
  });
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Let's go through it line by line:

var args = Array.prototype.slice.call(arguments);

JavaScript's arguments variable is similar to an array but it's not an array. You can try this yourself: arguments instanceof Array will give false. So applying the slice method from the Array prototype will simply convert arguments to a real array.

args.splice(0, 1);

This is to remove the first argument, which is arr in your case.

return arr.filter(function(element) {
  return args.indexOf(element) === -1;
});

This will go through all the numbers in arr and will check each one of them if it exists in the arguments. When indexOf() returns -1 it means the element was not found in the array.

Slice does not alter. It returns a shallow copy of elements from the original array. Elements of the original array are copied into the returned array.

Take this example

var object = {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
length: 5
};
var sliced = Array.prototype.slice.call( object, 3 );
 ['three','four']; //output

I've added comments, please see if it helps you to understand the function.

function destroyer(arr) {
  // arr just holds [1, 2, 3, 1, 2, 3]
  var args = Array.prototype.slice.call(arguments);
  // args contains nested array with all input params [[1, 2, 3, 1, 2, 3], 2, 3]
  args.splice(0, 1);
  //args is spliced and we have [2,3] in args
  //Filter arr=[1, 2, 3, 1, 2, 3] elements, condition it must not be in args i.e [2,3]
  return arr.filter(function(element) {
    return args.indexOf(element) === -1;
  });
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Please refer to the below documentation to read about arguments object used in this function:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments

  1. passe Arguments [Array[6], 2, 3]
  2. Arguments after splicing or remove first element of argument [2, 3]
  3. so closure function filters element which is present in first element of array with other two element. returning just [1, 1]

To understand what's going on, we need to understand the Function.prototype.call method .

It invokes the Array.prototype.slice method on the first argument you pass to it, which in this case is the magical JS arguments object , and then passes in whatever arguments follow.

Thus Array.prototype.splice is unnecessary, and you can just write:

function destroyer(arr) {
  var rest = Array.prototype.slice.call(arguments, 1);
  return arr.filter(function(element) {
    return rest.indexOf(element) === -1;
  });
}

in fact, this has been implemented in ES2015+ with the spread operator , so you could write:

function destroyer(arr, ...rest) {
  return arr.filter(function(element) {
    return rest.indexOf(element) === -1;
  });
}

In arr we will have [1,2,3,1,2,3] and in args we will have [[1,2,3,1,2,3],2,3] The filter function loop over arr and args.indexOf(element) will return -1 if element is not in args. So, for the first time in loop the element value is 1 and inside loop

args.indexOf(1) returns -1 because 1 is not present in args because at 0 index we have array and at 1st index we have 2 and at 2nd index we have 3. So the condition === -1 is true and returns 1 to the array that is going to be printed to the console.

for next element, ie, 2 in arr, the statement args.indexOf(2) returns the first index at which 2 is present ie, 1 in args array. for likewise entire loop will be executed for arr

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM