apply、call、bind 手写源码

1. apply:改变函数的 this 指向并立即调用,第一个参数是 this 指向,第二个参数为数组形式传入函数参数.

  Function.prototype.apply = function (thisArg) {
    let context = thisArg || window; // window 必须在 .html 文件使用
    let args = arguments[1] || [];
    context.fn = this;
    let result = context.fn(...args);
    delete context.fn;
    return result;
  };
  // 测试  
  console.log(Math.min.apply(null ,[15,3,516,9,145]));

2. call:与 apply 作用基本相同,不同的是,call 的参数是一个个传入的,不是以数组形式直接传入. 

  Function.prototype.call = function (thisArg) {
    let context = thisArg || window;
    let args = [];
    for (let i = 1; i < arguments.length; i++) {
      args.push(arguments[i]);
    }
    context.fn = this;
    let result = context.fn(...args);
    delete context.fn;
    return result;
  }
  // 测试
  console.log(Math.max.call(null, 15, 3, 65, 4, 2, 84));

或者利用已经实现的 apply 实现 call:

  Function.prototype.call = function (thisArg) {
    let args = [];
    for (let i = 1; i < arguments.length; i++) {
      args.push(arguments[i]);
    }
    return this.apply(thisArg, args);
  };

3. bind:返回一个函数,与 apply 和 call 有所不同,bind 会使得原函数的 this 指向 thisArg,也就是说 apply 和 call 的 this 指向被改变后会立刻执行一次并返回结果,而 bind 返回绑定 this 指向的函数,不会立即执行这个函数.

  Function.prototype.bind = function (thisArg) {
    let self = this;
    return function () {
      self.apply(thisArg, arguments);
    }
  };
var name = 'outer'; // let 定义的变量不会成为 window 的属性,因此使用 var 测试 let obj = { name: "inner" };
function printName() { console.log(this.name); }
printName();
// outer let printName_ = printName.bind(obj); printName_(); // inner

 

posted @ 2021-09-30 15:05  TwinkleG  Views(83)  Comments(0)    收藏  举报