Seek and Destroy - super confused

So I have read the solution and still have questions that I’m trying to work through.

1 - I understand what call(arguments) is doing, i.e. gets all the arguments passed in to the function. So I’m OK there.
2. Then slice is returning the arguments in an array, as a new array object. So that’s OK.
3 - I do not understand what Array.prototype is doing? I read this and I understand that the Array.prototype is like the ORIGINAL array from which all other arrays inherit properties etc. But I don’t get what purpose it is serving in this line of code.

Please help!

(You can ignore my code below; I was just messing around trying to understand arguments etc)

Your code so far

function destroyer(arr) {
  // Remove all the values
//   var args = Array.prototype.slice.call(arguments);
  console.log(arguments.length);
//   return arr;
}

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

Your browser information:

Your Browser User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36.

Link to the challenge:
https://www.freecodecamp.org/challenges/seek-and-destroy

Would this be helpful?

EDIT: I actually typed the following up before I initially posted the link to the SO thread above but realised that this may not be something you have come across yet, so the following explanation may also be useful to you:

Please take my explanation with a grain of salt because I’ve never tried explaining this to someone else!

I think your reasoning isn’t quite right:

1 - I understand what call(arguments) is doing, i.e. gets all the arguments passed in to the function. So I’m OK there.

call(arugments) doesn’t actually "gets all the arguments passed into the function—arguments is already all the arguments (in the form of an array-like object) passed into the function.

The key here is that arugments is:

  • Not an array
  • An array-like object (try console.log(arugments))

Since arugments is not an array, the slice() method is not available to it:

// Doesn't work because arguments is an array-like object that doesn't
// have the slice() method available to it
arguments.slice();

However, you can “borrow” the slice() method from the Array global object because it has the slice() method available to it (if you are interested, you can read more about prototypes here). In fact, you can “borrow” it from any arrays, but we’ll come back to that later.

Knowing that you can access the slice() method from the Array global object as Array.prototype.slice() is one thing, but using it on something else is another. When you write Array.prototype.slice() you are performing the slice() method on the global Array object, and this is where call() comes in—call() lets you set the object that slice() is operating on to whatever object you give to call() as an argument.

It’s probably technically incorrect—but it may be conceptually easier to think of it as call() lets you borrow the slice() method from Array.prototype and then uses it immediately (as in arguments.slice() now works because of call()).

Since arguments is an array-like object, slice() will go about and do its usually thing on the object and returns the numerically indexed values as an array.

I hope that helps!

1 Like

@honmanyau Thank you - that is really helpful. I think I have a better understanding of what is happening in that line of code now.

But now I have a question about the for loop -
The first for loop is going to go through all the values in arr so for testcase one that means these values are: 1, 2, 3, 1, 2, 3

Then, the second nested for loop is going to go through all the values in args, which for testcase one would be:[1, 2, 3, 1, 2, 3], 2, 3

So going through the logic, the first for loop will pick up the first value from arr which is 1.
Then it will check if that value (1) is equal to the first value in args. So my question is, will this logic look like this (as it iterates through the nested for loop):

Is 1 === [1, 2, 3, 1, 2, 3] // returns false
Is 1 === 2 // returns false
Is 1 === 3 // returns false

Thank you.

Yes, that should work fine, the nested loop logic should work perfectly well like that.

Note, regarding the original question, the Array.prototype.slice.call(arguments) method, the explanation you were given is pretty much spot on. But just don’t use it, use Array.from(arguments), which has the same effect, but doesn’t force the JS compiler to deoptimize your code (ie make it run slowly). You used to have to do the slice.call thing up until about four years ago, then they fixed that bit of JavaScript.

1 Like

Thank you @DanCouper!