call、apply、bind的区别和自定义

SegmentFault

共 2295字,需浏览 5分钟

 ·

2020-09-04 13:19

来源:SegmentFault 思否社区

作者:黄万通




区别call()/apply()/bind()


  • call(obj)/apply(obj): 调用函数, 指定函数中的this为第一个参数的值
  • bind(obj): 返回一个新的函数, 新函数内部会调用原来的函数, 且this为bind()指定的第一参数的值
  • 注意: 如果obj是null/undefined, this为window

  1. 应用
    call()/bind()应用: 根据伪数组生成真数组
    bind(): react中组件的自定义方法 / vue中的事件回调函数内部
  2. 自定义call()/apply()
    1). 给obj添加一个临时方法, 方法名任意, 值为当前函数
    2). 通过obj调用这个临时方法, 并将接收的参数传入
    3). 删除obj上的这个临时方法属性
  3. 自定义实现bind()
    1). 返回一个新函数
    2). 在新函数内部通过原函数对象的call方法来执行原函数, 指定原函数的this为obj
    指定参数为bind调用的参数和后面新函数调用的参数





自定义call()/apply()/bind()


  1. 自定义call()/apply()
    1). 给obj添加一个临时方法, 方法名任意, 值为当前函数
    2). 通过obj调用这个临时方法, 并将接收的参数传入
    3). 删除obj上的这个临时方法属性
    4). 代码
Function.prototype.call = function (obj, ...args) {      // this() 就是调用当前函数实例      // 处理obj是undefined或者null的情况      if (obj===undefined || obj===null) {        obj = window      }
// 给obj添加一个方法: tempFn: this obj.tempFn = this // 调用obj的tempFn方法, 传入rags参数, 得到返回值 const result = obj.tempFn(...args) // 删除obj上的temFn delete obj.tempFn // 返回方法的返回值 return result }


Function.prototype.apply = function (obj, args) {      // 处理obj是undefined或者null的情况      if (obj===undefined || obj===null) {        obj = window      }
// 给obj添加一个方法: tempFn: this obj.tempFn = this // 调用obj的tempFn方法, 传入rags参数, 得到返回值 const result = obj.tempFn(...args) // 删除obj上的temFn delete obj.tempFn // 返回方法的返回值 return result }


  1. 自定义实现bind()
    1). 返回一个新函数
    2). 在新函数内部通过原函数对象的call方法来执行原函数指定this为obj指定参数为bind调用的参数和后面新函数调用的参数
    3).代码

Function.prototype.bind = function (obj, ...args) {      // 返回一个新函数      return (...args2) => {        // 调用原来函数, 指定this为obj, 参数列表由args和args2依次组成        return this.call(obj, ...args, ...args2)      }    }




测试


   function fn(x, y) {      this.aaa = 3 // 会给改变this对象添加aaa属性的值为3,如果指定的对象为null会给window添加      console.log(x, y, this, arguments.length)      return x + y    }    const obj = {m: 0}    fn(10, 20) // 直接调用会在window全局对象下添加aaa属性    fn.call(obj, 10, 20) // 相当于obj.fn(10, 20) 打印: 10 20 obj 2    fn.apply(obj, [1, 2]) // 相当于obj.fn(1, 2) 打印: 1 2 obj 2    fn.call(null, 1, 2) // 和直接调用一样  打印: 1 2 Window 2    fn.bind(obj)(3, 4)  // 打印: 3, 4 obj 2    fn.bind(obj,10)(3, 4)  // 打印: 10, 3 obj 3





点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流。

- END -

浏览 17
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报