简体   繁体   中英

Understanding javascript borrowing methods

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?

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 .

One can use call keyword to implement method borrowing. Below example shows method borrowing.

var john = {
  name: "John",
  age: 30,
  isAdult: function() {
    console.log(this.name+"'s age is "+this.age);
    if (this.age > 18) {
      return true;
    } else {
      return false;
    }
  }
}

console.log(john.isAdult());

var rita = {
  name: "Rita",
  age: 15
}

console.log(john.isAdult.call(rita));

Observe the last line. How the keyword call is used and how rita object is passed to the function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM