2022-02-07 call,apply,bind

三个函数都能改变this指向,且三者第一个参数都为指定的this对象。区别如下:
1、call 传入参数列表,非数组; apply 参数格式为数组, bind参数列表。
2、call ,apply 为立即执行函数,bind 返回函数需要调用执行。

call方法的实现

Function.prototype.myCall = function (context) {
      // 先判断调用myCall是不是一个函数
      // 这里的this就是调用myCall的
      if (typeof this !== 'function') {
        throw new TypeError("Not a Function")
      }
      // 不传参数默认为window
      context = context || window
 
      // 保存this
      context.fn = this
 
      // 保存参数
      let args = Array.from(arguments).slice(1)   //Array.from 把伪数组对象转为数组
 
      // 调用函数
      let result = context.fn(...args)
 
      delete context.fn
 
      return result
 
    }


apply方法的实现

Function.prototype.myApply = function (context) {
      // 判断this是不是函数
      if (typeof this !== "function") {
        throw new TypeError("Not a Function")
      }
      let result
      // 默认是window
      context = context || window
 
      // 保存this
      context.fn = this
      // 是否传参
      if (arguments[1]) {
        result = context.fn(...arguments[1])
      } else {
        result = context.fn()
      }
      delete context.fn
      return result
    }

bind方法的实现


if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }
 
    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP
                                 ? this
                                 : oThis || this,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };
 
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
 
    return fBound;
  };
}

注意:在非严格模式下,第一个参数没传默认是window,在严格模式下是undefined,手写没考虑全面。

你可能感兴趣的:(2022-02-07 call,apply,bind)