This is the 26th day of my participation in the August More Text Challenge.

preface

These days, I found the codes of apply, call and bind written by hand when I scanned the topic and read the article. I can understand them now. And I thought there were some interesting details missing. So with this article, I’m going to comb through the handwriting of these functions, and I’m going to review the JavaScript execution mechanism.

Handwritten apply

The call method is the same except that it executes the function and passes the parameters differently.

Some breaking points:

  • About the this point in Apply. This refers to the caller of the Apply method, which executes the function itself. For example, f, f.ply (context, array) is declared. At this point, this in apply refers to f

  • What apply does is point this in function F to the context and execute the function. There are only three ways for this to point

  • This refers to the global object.

  • Called as a method on an object, this refers to the object.

  • The new + constructor, this, points to the newly generated object

  • If you want to change the reference to this in a function, the second way is obvious, so it’s natural to add a method f to the object context

  • After execution, delete the f method on the object and return the value of the function. Everything is fine again

    Function.prototype.apply = function (context, array) { context || (context=window) let func = this let caller = Symbol(“caller”) context[caller] = func let res = contextcaller delete context[caller] return res }

Write a call

As above, notice how the received parameters are written

Function.prototype.call = function (context, ... args) { context || (context=window) let func = this let caller = Symbol("caller") context[caller] = func let res = context[caller](... args) delete context[caller] return res }Copy the code

Write a bind

Bind returns a function, not the result of its execution

  • This instanceof F determines if it’s a call to new, and it saves this in its parent scope through a closure.

    Function.prototype.bind = function(context, … args) { if (typeof this ! == ‘function’) { throw new Error(“Type Error”); } var self = this;

    Return function F() {if(this instanceof F) {return new self(… args, … arguments) } return self.apply(context, […args, …arguments]) } }

If you want to refer to a complicated version

Refer to MDN Bind for Polyfill

Finally, attach a handwritten Apply that fills in some of the exception checks itself.

The new operator is not considered here. [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] [function.prototype.apply] Even if the constructor of prototype is null, it will not go there. I feel that there is a bit of resistance for further progress here, and my current skill is still not enough.

Function.prototype.apply = Function (context, array) {if(typeof context! =="object"&&typeof context ! =="function"){ throw new TypeError('context is not a object') } if(Object.getPrototypeOf(array)[@@iterator]){ throw new Type Error("CreateListFromArrayLike called on non-object") } context||(context=window) let func = this let caller = Symbol("caller") context[caller] = func let res = context[caller](... array) delete context[caller] return res }Copy the code

PS: I tried the handwritten code, and felt that it was not a very efficient combing because of the obvious weakness of my JS related system and the fear of the underlying specification. If, holding the mentality of learning, and it is difficult to talk about their own ideas, a little echoing feelings. You can only focus on learning and dig around one or two points of interest to protect your confidence and gain something at the same time. Focus on the gleaning of THE JS body of knowledge, rather than over-studying the details.

In short, according to my current level, I should pay attention to the expansion of the surface, and do not waste too much time on in-depth exploration of certain points. Day arch a pawn, rather than a battle, the mentality is better, to be more calm.