call、apply、bind的区别、使用、手写实现

call、apply、bind的区别、使用、手写实现

call、apply、bind都是改变this指向的方法

call、apply都是直接调用的

call第一个参数传入指定的上下文,其他参数接在后面一个个传入;apply第一个参数传入指定的上下文,其他参数以数组形式接在后面传入

bind返回一个函数,需要自己去调用

  1. call

    示例

    const person = {
      name:'小明',
      keep(age,school){
        console.log(`${this.name}今年${age}岁,上${school}`)
      }
    }
    const  student = {
      name:'小红',
    }
    person.keep(18,'大学') // 小明今年18岁,上大学
    person.keep.call(student,10,'小学') // 小红今年10岁,上小学
    

    手写实现

    Function.prototype.myCall = function (context,...args){ // 1.模仿传参方式
      context = context || window // 2.判断一下传入的上下文是否存在,若不存在就指向window
      const symbol = Symbol() // 3.用Symbol()取一个独一无二的值
      context[symbol] = this // 4.使用symbol值绑定this,为了避免重名
      const res =  context[symbol](...args) // 5.调用函数并存下返回值
      delete context[symbol] // 6.使用完删除
      return res // 7.返回值
    }
    person.keep.myCall(student,10,'小学')
    
  2. apply

    示例

    const person = {
      name:'小明',
      keep(age,school){
        console.log(`${this.name}今年${age}岁,上${school}`)
      }
    }
    const  student = {
      name:'小红',
    }
    person.keep(18,'大学')
    person.keep.apply(student,[10,'小学'])
    

    手写实现

    // 和call几乎一样,只有传参有区别
    Function.prototype.myApply = function (context,args){ // 第二个参数本身就是数组
      context = context || window
      const symbol = Symbol()
      context[symbol] = this
      const res =  context[symbol](...args) // 使用扩展运算符,将参数一个个传入
      delete context[symbol]
      return res
    }
    
  3. bind

    示例

    const person = {
      name:'小明',
      keep(age,school){
        console.log(`${this.name}今年${age}岁,上${school}`)
      }
    }
    const  student = {
      name:'小红',
    }
    person.keep(18,'大学')
    person.keep.bind(student)(10,'小学')
    

    手写实现

    Function.prototype.myBind = function (context,...args){ // ...args绑定时传的参数
      context = context || window
      const symbol = Symbol()
      context[symbol] = this
      return function (...innerArgs){ // 返回的是个函数;...innerArgs调用时传的参数
        context[symbol](...args,...innerArgs)
        delete context[symbol]
      }
    }
    person.keep.myBind(student,10)('小学')
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值