0

I don't understand the call function in javascript

function multiply(){
    console.log(arguments);
    console.log([].slice.call(arguments));
}

console.log(multiply(2,3));

The above function prints

// [Arguments] { '0': 2, '1': 3 }
// [ 2, 3 ]

So I see the value passed to call function is an following object

//[Arguments] { '0': 2, '1': 3 }

So I tried the following but it prints empty array,

function multiple(){
    console.log(arguments);
    console.log([].slice.call({ '0': 2, '1': 3 }));
}

console.log(multiple(2,3));

// [Arguments] { '0': 2, '1': 3 }
// []

Can anybody explain me why the call works in first case, and why it is not working in second case?

How exactly call and slice work?

Sugumar Venkatesan
  • 4,019
  • 8
  • 46
  • 77
  • have you read the [documentation on `Function.call`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call)? – Dan O Jul 27 '20 at 00:38
  • `arguments` is technically an Array-like Object. `const a = [].slice.call(arguments);` is used to cast an Array-like Object to an Array *(`a` in this case)*. You cannot use Array methods on an Array-like Object *(although they have a length, so you can loop)*, so an empty array's slice method is called in the context of an Array-like Object. By the way, in the second example you call `[].slice` in the context of a new Object Object, not an Object that is `instanceof Array`. – StackSlave Jul 27 '20 at 00:41

1 Answers1

1

In the first case you're simply passing the two numbers into call and there isn't an object being referenced as the first argument to call, so it will then identify those numbers as arguments, which is represented as an array-like object (it has a length) when logged. In the second case you're passing in an actual object (yes, identical looking to what ends up getting logged in the first case) as the first argument, but since it's an object, call thinks that object is what you're referencing as the this value that would be used for any subsequent argument values being passed in, of which you have none so it just returns an empty array. I'm relatively newer to JavaScript but from what I've seen the form [].slice.call(x, y, z) has often been used in the past to convert array-like lists into actual arrays, but these days with ES6 JavaScript you can just use a spread operator or Array.from() to do this much more easily. This post has more info on the slice and call type of pattern.

jason_r
  • 345
  • 1
  • 11