call、apply、bind解析、实现

文章详细介绍了JavaScript中call、apply和bind的用法及它们之间的异同,包括它们如何改变this指向以及参数传递的不同。此外,文章还解释了柯里化的概念,并提供了手动实现call、apply和bind的示例代码,最后通过测试函数展示了它们的实际应用。
摘要由CSDN通过智能技术生成

call、apply、bind

三者异同

相同点

都可以改变this指向

不同点

call(this指向,args1,args2,...) : 在call中传入函数参数,参数以参数列表的形式传入,函数调用call方法改变this指向后会直接执行;

apply(this指向,[args1,args2...]) : 在apply中传入函数参数,参数以数组的形式传入,函数调用apply方法改变this指向后会直接执行;

bind(this指向,args1,args2...) : 在bind中传入函数参数,参数以参数列表的形式传入,函数调用bind方法后不会直接执行,而是会返回一个永久改变this指向的函数(记为newFun),后续可调用newFun,并在此函数中传入参数(bind的这种参数传入方式,是函数柯里化的一个应用)。

拓展
在计算机科学中,柯里化(Currying)是把 接受多个参数的函数变换成 接受一个单一参数(最初函数的第一个参数)的函数,并且 返回接受余下的参数且返回结果的新函数的技术。

手写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
测试
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值