What does this code exactly mean?

var a = Array.prototype.slice.call(arguments,0)

Why does it return an array with all the arguments? I thought slice takes away arguments. What are the arguments and 0 parameters for?

Thanks,

Andrej

slice creates a slice of an array: it doesn’t take away anything - myArray.slice(0,5) says "create a new array made up of the values from index 0 to index 5 in the array myArray"

If you leave off the second argument, it slices up until the end of the array. So myArray.slice(0) says "create a new array made up of all the values in myArray (ie index 0 until the end)

call is a function that allows you to literally call a function. The reason this is sometimes useful is that you can borrow functions from other objects.

slice works on arrays, it is attached to the Array.prototype object.

arguments is an object that is available inside functions. It contains the arguments passed to the function. It is a bit like an array, but not quite.

If you want the arguments as an actual array, you can use slice(0) on them. But you can’t use it directly, you need to borrow it by using call. “Call the function slice (borrowed from Array.protoype) on the arguments object to create a copy of the arguments in an actual array”

This is quite confusing, and not recommended any more, so avoid doing it: either use rest parameters if you can:

function example (...someArgs) {
  // someArgs is already an array!
}

Or use Array.from if you can’t:

function example() {
  const args = Array.from(arguments);
}
1 Like

Ok wow thanks for the awesome explanation! So are arguments and parameters different because parameters are defined when calling the function and arguments are not right??

function destroyer(arr) {
  var args = Array.prototype.slice.call(arguments);

  for (var i = 0; i < arr.length; i++) {
    for (var j = 0; j < args.length; j++) {
      if (arr[i] === args[j]) {
        delete arr[i];
      }
    }
  }
  return arr.filter(Boolean);
}

This was the code, so the arguments were not defined but arr was for some reason. I dont know exactly why. Why doesnt arr count as an argument, is it a parameter?

How is args already an array I thought we were trying to convert it into an array with slice.call

Thanks

I thought it would be this challenge.


Just before the following, parameter is the variable, argument is the actual data, so for example

function add(x, y) { return x + y; }

add(1, 2);

The parameters are x and y, the arguments are 1 and 2.


Example, I have a function that takes any number of numbers as arguments and adds them up:

function addNumbers(...nums) {
  // nums is an array, don't need to
  // convert anything
  return nums.reduce((acc, num) => acc + num, 0);
}

So if I do addNumbers(1, 2, 3), in the function it will run reduce on an array [1,2,3] (returning 6)

function destroyer (arr, ...targets) {

With that function signature, arr is the first parameter, and targets will be represented inside the function as an array of the remaining arguments (the onces you want to destroy in arr)

If I use rest parameters this way, I don’t need to do anything special to get the arguments: I’ve already explicitly defined them

It does count. In JavaScript, you can pass as many arguments as you want to a function: in this case, like

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

arr is the first parameter – in this case the argument is [1,2,3,4]. The other arguments in your code aren’t defined, and this is why you’re using slice. You need a way to get those remaining arguments. If you use rest parameters, it can be made explicit (this is why it is recommended in the documentation)

But if you don’t use rest parameters, then what you have to do is extract that 1 and 2 somehow. So can use Array.prototype.slice.call(arguments, 0), or can use Array.from(arguments) (which is a lot clearer IMO)

function destroyer (arr) {
  const args = Array.from(arguments)

args is an array containing all the arguments, so for destroyer([1,2,3,4], 1, 2) it’ll look like [[1,2,3,4], 1, 2]

Ok I am reading through and first wanted to ask

I thought …nums would spread the array not making it an array anymore. I thought the spread operator was used to get items out of an array

I dont know how to tag you but I posted a question

No, you’re misunderstanding. You’re not looking at how this function is called. This:

function addNumbers (...nums) {

Is

  • a function called addNumbers
  • with one parameter (nums)
  • that represents any number of arguments
  • and inside the function those arguments are represented as an array, under the variable name nums
addNumbers(1,2,3,4,5);

No array, the input isn’t an array.

In ES5, if you want a function (or method) to accept an arbitrary number of arguments, you must use the special variable arguments
In ES6, you can declare a rest parameter via the ... operator

https://exploringjs.com/es6/ch_parameter-handling.html#sec_rest-parameters

In my other example

destroyer (arr, ...targets) {
  • Two parameters, arr and targets
  • arr is the first parameter, it represents a single argument
  • targets is the second parameter, it represents any number of remaining arguments.
destroyer ([1,2,3,4], 1, 2)

The first argument is [1,2,3,4], that is assigned to the variable arr. The second and third arguments are 1 and 2, they get assigned to the variable targets as an array like [1,2]

It’s the rest operator, not spread: it’s very much connected, hence same syntax, but not quite the same.

1 Like

Thanks so much! Howcome Array.from does not have Arra.prototype?

It’s just a function attached directly to the Array object. Same as all Math methods are just functions attached to an object called Math, or see Object.keys or Object.values (or parseInt or console.log) or whatever.

It doesn’t need to be attached to a prototype, it doesn’t use this. It needs to go somewhere rather than just floating around, so makes sense to attach it to the Array object

// Array.prototype.slice
[1,2,3].slice(1)
    ^
    |
 `this`

Vs

Array.from({ 0: 1, 1: 2, 2: 3, length: 3})
// returns [1,2,3]