- First, we need to understand the use of bind
- Fn. bind(obj,x,y,…) Obj is the binding object. This refers to the object. X and y are the binding parameters.
- With that in mind, let’s just do it
The first step is to bind obj to the parameter
Function.prototype.myBind = function(){
const targetFn = this; // Target function
const [targetObj,...targetArgs] = [...arguments]; // Destruct objects and bind parameters
if(typeoftargetFn ! = ='function') {
throw `The ${this} must be a function`
}
return function(){ targetFn.apply(targetObj,targetArgs); }}Copy the code
In the second step, we find that the above function cannot pass parameters after generating a new function, so we modify it
Function.prototype.myBind = function(){
const targetFn = this; // Target function
const [targetObj,...targetArgs] = [...arguments]; // Destruct objects and bind parameters
if(typeoftargetFn ! = ='function') {
throw `The ${this} must be a function`
}
return function(. args){ targetFn.apply(targetObj,[...targetArgs, ...args]); }}Copy the code
The third step is that the function we bind must support new and we can’t do new correctly because we’re always working on the target object so we have to say do we use new
Function.prototype.myBind = function(){
const targetFn = this; // Target function
const [targetObj,...targetArgs] = [...arguments]; // Destruct objects and bind parameters
if(typeoftargetFn ! = ='function') {
throw `The ${this} must be a function`
}
const newFn = function(. args){
const isNewFlag = this instanceof newFn // If new is applied, then the object that comes out of new, which is this, must refer to an instance of newFn, which will be true;
targetFn.apply(isNewFlag ? this : targetObj,[...targetArgs, ...args]);
If it is the new operator, all bindings should be on the object new at the moment
}
return newFn
}
Copy the code
In step 4, the new object’s __proto__ refers to the new bind function. However, the prototype of the current function does not refer to the original targetFn prototype, so we need to set it Note that you can’t reference the function directly or you’ll change the targetFn prototype if you change the prototype of the new bind function
Function.prototype.myBind = function(){
const targetFn = this; // Target function
const [targetObj,...targetArgs] = [...arguments]; // Destruct objects and bind parameters
if(typeoftargetFn ! = ='function') {
throw `The ${this} must be a function`
}
const newFn = function(. args){
const isNewFlag = this instanceof newFn // If new is applied, then the object that comes out of new, which is this, must refer to an instance of newFn, which will be true;
targetFn.apply(isNewFlag ? this : targetObj,[...targetArgs, ...args]);
If it is the new operator, all bindings should be on the object new at the moment
}
const temporarilyFn = function(){};
temporarilyFn.prototype = targetFn.prototype;
newFn.proptotype = new temporarilyFn();
return newFn
}
Copy the code
So that’s our bind self-implementation. One thing that’s different from the browser is that the browser doesn’t have the prototype attribute. But when it uses the new operator, it can still reference its __proto__ as targetFn prototype