Previously, I only know the general usage of these three things, but I do not know how to implement them. Today, I will study them.
I. Call simulation implementation
To tap into the inner workings of Call, you must know how it is used. If the first argument is undefined, it defaults to window in non-strict mode, and undefined in strict mode.
Internally, Call does several things
1. Use the function that calls call as a property of the object represented by the first argument to call
2. Pass arguments to this function and call it
3. Delete this function from the object
4. Determine if the first argument exists or is null, and set context to window
5. Return the value returned by the function
Function.prototype.call2 = function (context, ... Args) {var context = context | | the window / / to judge whether the execution context of the incoming is empty, if the null point to the window context. The fn = this; Var res = context.fn(... Args) // Call the function and pass in the second argument of call, which is the argument delete context.fn // Delete the property return res // Fanhui directly if there is a value returned}Copy the code
2. Simulation implementation of apply
The internal principle of apply is basically the same as that of call. The difference is that the second parameter of apply is array, and the second parameter of call is one by one
To achieve the following
Function.prototype.apply2 = function (context,args) { var context = context || window; context.fn = this; let result = context.fn(... Args) delete context.fn return result; }Copy the code
Three. Bind simulation implementation
Call timing is different
The use of bind is a little different from the previous two weeks. Calls and apply will execute immediately after they are called, while bind will return an original function that has been altered by this, leaving the programmer to choose when to call it.
The number of times the parameter is passed is different
Call and apply pass arguments only once when they are called, while bind can pass arguments not only the first time it is called, but also later in a function that returns a change in the reference to this.
There are several things that bind does internally
1. Change this to a function but instead of executing it immediately, return a function for the programmer to call.
2. Pass the first parameter and the later parameter as the same parameter to the function
3. This refers to the instance created by the constructor when the function returned by bind is used as the constructor, and to the specified execution context otherwise
4. An error occurs when this is not a function.
Function.prototype.bind2 = function (context, ... args1) { if (typeof this ! == "function") { throw new Error("Function.prototype.bind - what is trying to be bound is not callable"); } let self = this; let args1 = [...args1] let fBound = function (... args2) { let args2 = [...args2] return self.apply(this instanceof fBound ? This: context, [...args1,...args2]) // Change this to point to and pass arguments to the return function} fbound. prototype = object.create (this.prototype); // If the return function is a constructor, then the prototype of the constructed instance needs to refer to the prototype object of the return function. Return fBound // Return the function that changes the function executed by this and let the programmer call it himself}Copy the code
Iv. Simulation implementation of new
What does new do when we instantiate an object with new
New does several things internally
Create a new object (instance)
2. Point the object’s implicit stereotype to the constructor’s display stereotype
3. Pass the constructor this to the instance and pass the argument inside
4. Determine whether the constructor returns an object or a primitive type. If it returns an object, return an instance if it does not
function _new(fn, ... __proto__ = fn. Prototype let res = fn. Call (obj,... Args) return typeof res === object? Res: obj // Check whether the return value is an object, if yes, return this object, if not, return this empty object}Copy the code