call, apply, bind analysis, implementation

call、apply、bind

The similarities and differences of the three

Same point

You can change the direction of this

difference

call(this points to, args1, args2,...) : Pass in function parameters in the call, the parameters are passed in in the form of a parameter list , and the function call call method will be executed directly after changing the this point;

apply(this points to, [args1,args2...]) : Pass in function parameters in apply, the parameters are passed in in the form of an array , and the function will be executed directly after the function calls the apply method to change the this point;

bind(this points to, args1, args2...) : Pass in function parameters in bind, the parameters are passed in in the form of a parameter list , the function will not be executed directly after calling the bind method, but will return a permanent change to this point function (denoted as newFun), newFun can be called later, and parameters can be passed in this function (this method of parameter passing in bind is an application of function currying).

Extended
in computer science, currying is the transformation of a function that accepts multiple arguments into a function that accepts a single argument (the first argument of the original function) and returns a new function that accepts the remaining arguments and returns a result Technology.

Handwritten call, apply, bind

call

function myCall(_this){
            // this指向myCall函数的调用者
    		//_this为改变后的this指向
            // 如果未传_this,则默认为window
            _this=_this||window
    		//获取传入参数,并去除第一项,即为要传入调用函数的参数
            let args=[...arguments].filter((value,index)=>index!==0)
            _this.fun=this
            let res=_this.fun(...args)
            delete _this.fun
            return res
        }
//绑定到函数原型上
Function.prototype.myCall=myCall

apply

function myApply(_this){
            _this=_this||window
            let args=[...arguments][1]
            _this.fun=this
            let res=_this.fun(...args)
            delete _this.fun
            return res
        }
Function.prototype.myApply=myApply

bind

function myBind(_this){
            _this=_this||window
    		//this指向myBind函数的调用者
            let that=this
            let args=[...arguments].filter((value,index)=>index!==0)
            let newFun=function(){
                //this指向newFun函数的调用者
                args.push(...arguments)
                _this.fun=that
                let res=_this.fun(...args)
                delete _this.fun
                return res
            }
            return newFun
        }
Function.prototype.myBind=myBind

test

function test(name,age) {
    console.log(name,age,this.name1,this.age)
}
let obj={
    name1:'zs',
    age:18
}

//myCall的调用者为test,所以在myCall中,this指向test
test.myCall(obj,'hh',30) //hh 30 zs 18
test.myApply(obj,'ls',19) //ls 19 zs 18
let bindres=test.myBind(obj,'bind')
bindres(20) //bind 20 zs 18

Guess you like

Origin blog.csdn.net/sxp19980829/article/details/128727635