zyy7259
zyy7259

Reputation: 525

Confusion about bind & call in JavaScript

When I'm reading Array.prototype.slice in MDN, I found an example: Array-like objects:

Here is the sample code:

var unboundSlice = Array.prototype.slice;
var boundSlice = Function.prototype.call.bind(unboundSlice);

function list() {
  return boundSlice(arguments, 0);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

What's the function call process when call list(1, 2, 3)?

  1. I know that in list(), it calls boundSlice([1, 2, 3], 0). But what happened in boundSlice?
  2. I understand that boundSlice is a bound function to the call() function of Function.prototype, with the this value set to the slice() function of Array.prototype.
  3. slice() is the this, then how to produce result [1, 2, 3]? I guess the final call is [1, 2, 3].slice(0), am I right? If I'm right, how could this happen, can anyone explain the inner process to me?

Upvotes: 2

Views: 82

Answers (1)

plalx
plalx

Reputation: 43718

var boundSlice = Function.prototype.call.bind(unboundSlice);

This is basically:

var boundSlice = function (thisArg, arg1) {
    unboundSlice.call(thisArg, arg1);
};

The tricky part is how does it know to execute the call operation on unboundSlice? That's because the call method uses the this value internally to know which function to invoke and since we set the this value to unboundSlice by using ...call.bind(unboundSlice) it invokes this method.

For example, when we do Array.prototype.slice.call(arguments, 0), the this value inside call will be Array.prototype.slice since the this value is always the left side of the . when not altered.

You assumptions were right about the result of list(1, 2, 3) being [1, 2, 3].slice(0).

Note that list can simply be implemented as:

function list() {
    return Array.prototype.slice.call(arguments);
    //or return [].slice.call(arguments);
}

Upvotes: 2

Related Questions