手写call、apply、bind方法及区别总结

call、apply和bind区别:

相同点:
  作用相同,都是动态修改this指向;都不会修改原先函数的this指向。
  
异同点:

  1. 执行方式不同:
  • call和apply是改变后页面加载之后就立即执行,是同步代码
  • bind是异步代码,改变后不会立即执行;而是返回一个新的函数
  1. 传参方式不同:
  • call和bind传参是一个一个逐一传入
  • apply可以使用数组的方式传入的 。
  • call和 apply不能使用剩余参数的方式传参,bind 可以使用剩余参数的方式传入(柯里化)。
  1. 修改this的性质不同:

call、apply只是临时的修改一次,也就是call和apply方法的那一次;当再次调用原函数的时候,它的指向还是原来的指向。

1.手写call方法

  1. 定义myCall方法
  2. 设置this并调用原函数
  3. 接收剩余参数并返回结果
  4. 使用Symbol调优
//1.定义myCall方法
//3.接收剩余参数并返回结果
Function.prototype.myCall=function(thisArg,...args){
  // 2.设置this并调用原函数
    // thisArg:作为传入的设置为this的对象
    // this:原函数(func)
    console.log('thisArg:',thisArg);
    console.log('this:',this)
    // 给thisArg加一个一定和原属性不重名的新属性(方法)
    const key = Symbol('key');
    thisArg[key]=this;//动态增加的属性名,[]动态解析属性名解析为Symbol值
    const res = thisArg[key](...args);
    delete thisArg[key] // 删除原对象中动态添加的方法,保持原对象不被修改
    // thisArg.fun=this;//如果采用thisArg.key的形式,相当于属性名就叫key
    //const res = thisArg.fun(...args);
    // delete thisArg.fun  
    return res
}

const person={
    name:'小明'
}
function func(numA,numB){
    console.log(this) 
    console.log(numA,numB)
    return numA+numB
}
const res= func.myCall(person,2,8);//this指向person, 立即执行
console.log('返回值为:',res);//返回值:10
func(1,2);//this指向window

const food={
    name:'面包'
}
function fun2(num1,num2,num3){
    console.log(this);
    console.log(num1,num2,num3);
    return num1+num2+num3;
}
const res2=fun2.myCall(food,2,4,6);
console.log('res2:',res2);// res2: 12

2.手写apply方法

  1. 定义myApply方法
  2. 设置this并调用原函数
  3. 接收参数并返回结果
 Function.prototype.myApply = function(thisArg,args){
     const key = Symbol('key');
     thisArg[key]=this;
     const res = thisArg[key](...args);
     delete thisArg[key]
     return res
 }
 const food={
     name:'面包'
 }
 function fun2(num1,num2,num3){
     console.log(this);
     console.log(num1,num2,num3);
     return num1+num2+num3;
 }
 const res =fun2.myApply(food,[2,8,10]);//this指向food,以数组方式传入参数,立即调用执行
 console.log('返回值为:',res)//20
 funs(1,2,3);//this指向window

3.手写bind方法

  1. 定义myBind方法
  2. 返回绑定this的新函数
  3. 合并绑定和新传入的参数
  // 1. 定义myBind方法
   Function.prototype.myBind = function(thisArg,...args){
        // 2.返回绑定this的新函数
        return (...reArgs)=>{
            // this:原函数(func) 
            //3. 合并绑定和新传入的参数
           return this.call(thisArg,...args,...reArgs);        
        }
    }
    const person={
        name:'小明'
    }
    function func(numA,numB,numC,numD){
        console.log(this);
        console.log(numA,numB,numC,numD)
        return numA+numB+numC+numD
    }
    const bindFunc=func.myBind(person,1,2);
    console.log('bindFunc:',bindFunc);// 函数, this指向person
    const res=bindFunc(3,4); // 再次调用执行
    console.log('返回值:',res);// 10

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值