.bind 和.call和.apply

171 阅读1分钟

bind

要点:

  • this是一个函数
  • 谁调用myBind函数,this就指向谁
  • 这里调用myBind的是函数add
// @ts-ignore
Function.prototype.myBind = function (ctx: any, ...args: any[]) {
  const fn = this;

  return (...more: any[]) => {
    return fn.call(ctx, ...args, ...more);
  };
};

测试

let jack = { name: "jack" };
function add(a, b, c) {
    console.log(a + b + c, this.name);
}
add.myBind(jack, "1")("2", "3");

apply

Function.prototype.myApply = function (ctx: any, args: any[]) {
  ctx = undefined_null(ctx) ? globalThis : Object(ctx);

  const fnKey = Symbol();
  const fn = this;
  ctx[fnKey] = fn;

  const res = ctx[fnKey](...args);
  delete ctx[fnKey];
  return res;
};

function undefined_null(v: any) {
  if (v === null) return true;
  if (v === undefined) return true;
  return false;
}

测试

let tom = { name: "tom" };
function add(a = 1, b = 1) {
  console.log(this);
  return a + b;
}

let res = add.myApply(tom, [1, 2]); // console.log({name: 'tom'})
console.log(res); // console.log(3)

call

// @ts-ignore
Function.prototype.myCall = function (ctx, ...args) {
  ctx = undefined_null(ctx) ? globalThis : Object(ctx);

  const fn = Symbol();
  ctx[fn] = this;

  const res = ctx[fn](...args);
  delete ctx[fn];
  return res;
};

function undefined_null(v: any) {
  if (v === null) return true;
  if (v === undefined) return true;
  return false;
}

测试

// 测试
let tom = { name: "tom" };
function add(a = 1, b = 1) {
  console.log(this);
  return a + b;
}

let res = add.myCall(tom, 1, 2); // console.log({name: 'tom'})
console.log(res); // console.log(3)