Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding javascript borrowing methods

Tags:

javascript

There is a lot of explanation about how to convert a function's arguments to a real array.

But I have found it very interesting when you simplify the code with the help of bind.

MDN Array.prototype.slice - Array-like objects

MDN Function.prototype.bind - Creating shortcuts

For example:

function list() {
  return Array.prototype.slice.call(arguments);
}

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

Simplified call:

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

function list() {
  return slice(arguments);
}

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

It is working the same way if you use apply instead of call:

var slice = Function.prototype.apply.bind(unboundSlice);

Which can be even shortened by using call from any function instance, since is the same as the one in the prototype and same approach with slice from an array instance:

var slice = alert.call.bind([].slice);

You can try

var slice = alert.call.bind([].slice);

function list() {
    console.log(slice(arguments));
}

list(1, 2, 3, 4);

So the first very weird thing is coming into my mind is calling bind on apply, but the first argument of bind should be an object (as context) and not a function (Array.prototype.slice).

The other is that is working with both call and apply the same way.

I am writing javascript for quite a long time and using these methods day to day confidently but I can not wrap my head around this.

Maybe I am missing some very fundamental detail.

Could somebody give an explanation?

like image 625
cstuncsik Avatar asked Jul 07 '16 13:07

cstuncsik


People also ask

How do JavaScript methods work?

JavaScript methods are actions that can be performed on objects. A JavaScript method is a property containing a function definition. Methods are functions stored as object properties.


Video Answer


1 Answers

the first argument of bind should be an object (as context)

Yes.

and not a function (Array.prototype.slice).

Why not? For one, all functions are objects, so nothing wrong here.

From another perspective, if you use slice.call(…) or slice.apply(…) then the slice object is the context (receiver) of the call/apply method invocations.

What is the difference between binding apply and call?

There is no difference between applyBoundToSlice(arguments) and callBoundToSlice(arguments). The difference is applyBoundToSlice(arguments, [0, n]) vs callBoundToSlice(arguments, 0, n) if you want pass start and end arguments to the slice.

like image 179
Bergi Avatar answered Sep 21 '22 13:09

Bergi