bind & call & apply

2021-09-09  本文已影响0人  菜鸡前端

网上很多文章 apply 的写法是错误的,Function.prototype.apply 第二个参数必须为1个数组,拍平后传给函数实例。

1. bind

Function.prototype.bind = function(context, ...args) {
  if (typeof this !== 'function') {
    throw new Error("Type Error");
  }
  var self = this;

  return function F() {
    // 考虑 new 操作符
    if(this instanceof F) {
      return new self(...args, ...arguments)
    }
    return self.apply(context, [...args, ...arguments])
  }
}

2. call

Function.prototype.myCall = function (context, ...args) {
  if (context === null || context === undefined) {
    // 指定为 null 和 undefined 的 this 值会自动指向全局对象
    context = window
  } else {
    // 值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的实例对象
    context = Object(context)
  }

  const key = Symbol();
  context[key] = this;
  const res = context[key](...args);
  delete context[key];
  return res;
}

// 用例
function fn(a) {
  console.log(this, a)
}
fn.myCall({ name: 1 }, 2)

3. apply

Function.prototype.myApply = function (context, args) {
  if (context === null || context === undefined) {
    // 指定为 null 和 undefined 的 this 值会自动指向全局对象
    context = window
  } else {
    // 值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的实例对象
    context = Object(context)
  }

  const key = Symbol();
  context[key] = this;

  const res = (context[key])(...args);
  delete context[key];
  return res;
}

// 用例
function fn(a) {
  console.log(this, a)
}
fn.myApply({ name: 1 }, [2])
上一篇下一篇

猜你喜欢

热点阅读