call,apply,bind学习记录

1.简介

call,apply,bind都是可以改变this指向的三种方法,主要有什么区别呢?
call: 可以传入多个参数,第一个参数是需要this指向的哪个对象;后续的参数是调用call方法函数中的参数,是一个一个传入的;
apply:可以传入多个参数,第一个参数是需要this指向的哪个对象;后续的参数是调用call方法函数中的参数,是数组形式传入的;
bind:传入的参数是和call是一样的;但是与call,apply不同的一点是,call与apply调用之后会自动执行函数方法,返回结果;但是bind是需要手动调用的,返回一个函数;

2.实操demo

定义Per与Per1两个对象如下:

let Per={
    name:'coco',
    say(age,sex){
        console.log(`我叫${this.name}年龄是${age}性别是${sex}`)
    }
}
let Per1={
    name:'taotao'
}
//我们可以打印下Per.say(14,'女')
Per.say(14,'女')  //我叫coco年龄是14性别是女

使用原生的call,apply,bind来看下

  Per.say.call(Per1,23,'男')  //我叫taotao年龄是23性别是男
  Per.say.apply(Per1,[26,'男'])  //我叫taotao年龄是26性别是男
  let fun=Per.say.bind(Per1,,28,'男')
  console.log(fun)  //打印结果如下
  // ƒ say(age,sex){
  //    console.log(`我叫${this.name}年龄是${age}性别是${sex}`)
  //  }
  fun()  //需要手动调用    //我叫taotao年龄是28性别是男

接下里我们自己动手实现下
1.call
代码如下:

Function.prototype.myCall=function(context){
         //context 指的是需要this指向的对象,就像上面的例子一样,指的是Per1
         //context存在不,存在即是对象本身,不存在指向window
        context=context || window
        // this指的是需要改变this指向的方法对象,如上面的例子即是Person.say方法
        // 我们需要的操作就是在context对象上挂载一个同样的方法指向this即可;又因为say是唯一的,我们需要Symbol来帮忙
        const fn=Symbol()
        context[fn]=this
        console.log(context[fn])  
        // 打印结果是
        // ƒ say(age,sex){
        //     console.log(`我叫${this.name}年龄是${age}性别是${sex}`)
        // } 
        // 处理参数,call方法中第一个参数是指需要指向this的对象,后面的参数就是需要改变this的方法中的参数
        let args=[...arguments].slice(1) || []  //截取参数除了第一个参数外的所有参数
        let result=context[fn](...args)  //调用挂载的方法
        delete context[fn]  //删除加上的方法
        return result  //返回结果
}

Per.say.myCall(Per1,13,'女')   ///我叫taotao年龄是13性别是女

2.apply
代码如下:

Function.prototype.myApply=function(context){
    context=context || window
    let fn=Symbol()
    context[fn]=this
    let args=arguments[1]  || []  //传入的参数是数组的形式,如果没有传入定义为空数组,为了后面好解构
    console.log(args)   //  打印结果是[12, '男']
    let result=context[fn](...args)
    delete context[fn]
    return result
 }
 
  Per.say.myApply(Per1,[12,'男'])   //我叫taotao年龄是12性别是男

3.bind
代码如下:

Function.prototype.myBind=function(context){
   context=context||window
   //定义self,保存this,在返回的函数中使用
   let self=this
   //先获取外部参数
   let args=[...arguments].slice(1) || []
   //返回一个函数,手动调用
   return function(){
    //  在获取内部函数的参数,因为bind传参是可以柯里化的
     let newArgs=[...arguments] ||[]
    //  合并后的参数
     let resArgs=[...args,...newArgs]
     //直接使用apply方法来改变this的指向
     self.apply(context,resArgs)
   }
}

let fun=Person.say.myBind(Person1,14,'男')
fun()   我叫taotao年龄是14性别是男

//还可以下面的传参,都是可以实现的
let fun=Person.say.myBind(Person1,14)
fun('男')   我叫taotao年龄是14性别是男

总结:简单的记录下call,apply,bind的学习,加油,学习前端每一天!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值