js手写——绑定函数apply/call/bind

103 阅读2分钟

一、绑定函数介绍及其作用

在js中,有apply、call、bind三个绑定函数,他们的作用就是将对应的函数指定绑定到对应的对象上

绑定函数的作用主要是为了修改this指针的指向,使得在函数中的this指向发生改变。

二、原生绑定函数用法

function sum(num1, num2, num3) {
  console.log(num1 + num2 + num3, this);
}
sum.bind("111")(10, 20, 30);
sum.apply("111", [10, 20, 30]);
sum.call("111", 10, 20, 30);

sum.bind(222)(40, 20, 30);
sum.apply(222, [40, 20, 30]);
sum.call(222, 40, 20, 30);

sum.bind({ name: "aaaa" })(70, 20, 30);
sum.apply({ name: "aaaa" }, [70, 20, 30]);
sum.call({ name: "aaaa" }, 70, 20, 30);

2.1 bind函数

参数:第一个参数是绑定的对象,后续参数作为函数的参数值 返回值:绑定好指定对象的函数

sum.bind("111")(10, 20, 30)表示sum函数中的this绑定在Stirng("111")对象上,同时运行sum(10, 20, 30)

2.2 apply函数

参数:第一个参数是绑定的对象,第二个参数是相应函数的参数值(数组) 返回值:绑定好指定对象并且运行函数得到的结果

sum.apply("111", [10, 20, 30])表示sum函数中的this绑定在Stirng("111")对象上,同时运行sum(10, 20, 30)

2.3 call函数

参数:第一个参数是绑定的对象,后续参数是相应函数的参数值 返回值:绑定好指定对象并且运行函数得到的结果

sum.call("111", 10, 20, 30)表示sum函数中的this绑定在Stirng("111")对象上,同时运行sum(10, 20, 30)

三、手写apply/call/bind函数

以sum函数为例

function sum(num1, num2, num3) {
  console.log(num1 + num2 + num3, this);
}

3.1 yzApply

Function.prototype.yzApply = function(thisArg, argArray) {
  const fn = this;
  thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : thisArg;
  const symbol = Symbol('fn');
  thisArg[symbol] = fn;
  const result = thisArg[symbol](...argArray);
  delete thisArg[symbol];
  return result;
}
sum.yzApply("aaa", [10, 20, 30]);

3.2 yzCall

Function.prototype.yzCall = function(thisArg, ...args) {
  const fn = this;
  thisArg = (thisArg !== undefined && thisArg !== null) ? Object(thisArg) : thisArg;
  const symbol = Symbol('fn');
  thisArg[symbol] = fn;
  const result = thisArg[symbol](...args)
  return result;
}
sum.yzCall("bbb", 20, 30, 40);

3.1 yzBind

Function.prototype.yzBind = function(thisArg, ...args) {
  const fn = this;
  thisArg = (thisArg !== undefined && thisArg !== null) ? Object(thisArg) : thisArg;
  const symbol = Symbol('fn');
  thisArg[symbol] = fn;

  function bind(...args2) {
    const result = thisArg[symbol](...args, ...args2);
    delete thisArg[symbol];
    return result;
  }

  return bind;

}
sum.yzBind("ccc").yzBind("abc")(30, 40, 50);