1. 程式人生 > >前端基礎——call、apply、bind的實現

前端基礎——call、apply、bind的實現

call方法的實現

  Function.prototype.myCall = function (obj, ...args) {
    if (typeof this !== 'function') {
      throw new Error(this + '.call is not a function');
    }
    if (obj === null || obj === undefined) {
      obj = window;
    } else {
      obj = Object(obj);
    }
    Object.prototype.
fn = this; // 步驟1 let result = obj.fn(...args); delete Object.prototype.fn; return result; }

很多人在步驟1那裡,寫的是obj.fn = this; 先不說覆蓋的問題,後面在執行obj.fn()時,函式裡面的this的確指向obj,但此時的obj裡面多了個fn屬性。
測試一下上面寫的。

  window.a = 2;
  let obj = {
    a: 1,
    b: 3
  }
  let addNum = function (...args) {
    let
sum = args.reduce((previous, current) => previous + current); console.log(this, sum); return this.a; } let res1 = addNum.call(obj, 1, 2, 3); console.log(res1); let res2 = addNum.myCall(obj, 1, 2, 3); console.log(res2);

結果:
在這裡插入圖片描述

apply方法的實現

跟call方法相比,也就是接收引數的形式不同而已,apply以陣列的形式接收引數。

  Function.prototype.myApply = function (obj, args) {
    if (typeof this !== 'function') {
      throw new Error(this + '.call is not a function');
    }
    if (obj === null || obj === undefined) {
      obj = window;
    } else {
      obj = Object(obj);
    }
    Object.prototype.fn = this;
    let result = obj.fn(...args);
    delete Object.prototype.fn;
    return result;
  }

測試:

  window.a = 2;
  let obj = {
    a: 1,
    b: 3
  }
  let addNum = function (...args) {
    let sum = args.reduce((previous, current) => previous + current);
    console.log(this, sum);
    return this.a;
  }
  let res1 = addNum.apply(null, [1, 2, 3]);
  console.log(res1);
  let res2 = addNum.myApply(null, [1, 2, 3]);
  console.log(res2);

結果:
在這裡插入圖片描述

bind方法的實現

  Function.prototype.myBind = function (obj, ...args) {
    if (typeof this !== 'function') {
      throw new Error(this + '.call is not a function');
    }
    if (obj === null || obj === undefined) {
      obj = window;
    } else {
      obj = Object(obj);
    }
    let _this = this;
    return function (...args1) {
      let arg = args.concat(args1);
      Object.prototype.fn = _this;
      let result = obj.fn(...arg);
      delete Object.prototype.fn;
      return result;
    }
  }

測試:

  window.a = 2;
  let obj = {
    a: 1,
    b: 3
  }
  let addNum = function (...args) {
    let sum = args.reduce((previous, current) => previous + current);
    console.log(this, sum);
    return this.a;
  }
  let res1 = addNum.bind(undefined, 1, 2, 3);
  console.log(res1(4, 5));
  let res2 = addNum.myBind(undefined, 1, 2, 3);
  console.log(res2(4, 5));

結果:
在這裡插入圖片描述