区别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

黄万通
16 声望0 粉丝