面试官还在让你手写JS中call apply bind?看我一文

2023-02-02  本文已影响0人  郝同学1208

文章序

这是个老生常谈的问题了,就算不让你手写,那也大概率会问到你他们三个的区别和原理,本文就旨在一文帮你彻底搞懂这三个方法

使用方法

myFunction.call(obj,arguments1,arguments2,arguments3...);
执行原函数,函数中this指向参数obj,原函数myFunction参数为后面的arguments

myFunction.apply(obj,[arguments1,arguments2,arguments3...]);
执行原函数,函数中this只想参数obj,原函数myFunction入参为后面的arguments数组

myFunction.bind(obj);
返回一个函数,该函数的入参传给原函数myFunction,如需执行可以写为myFunction.bind(obj)(arguments1,arguments2,arguments3...);

手写

原始用法

请看下方示例,除了res0返回undefined undefined engineer web,其余均返回hpf 24 engineer web

  function Person(name, age) {
    this.myName = name;
    this.myAge = age;
  }
  const obj = new Person("hpf", 24);

  function sayName(work, type) {
    return this.myName + " " + this.myAge + " " + work + " " + type;
  }

  let res0 = sayName("engineer", "web");
  let res1 = sayName.call(obj, "engineer", "web");
  let res2 = sayName.apply(obj, ["engineer", "web"]);
  let res3 = sayName.bind(obj)("engineer", "web");

  console.log(res0);  //undefined undefined engineer web
  console.log(res1);  //hpf 24 engineer web
  console.log(res2);  //hpf 24 engineer web
  console.log(res3);  //hpf 24 engineer web

call

参考call的使用方法,我们可以理解为在入参obj对象上新增一个sayName函数,然后将参数传入,执行该函数,执行结束后删除掉该函数

  function myCall(obj) {
    if(arguments.length === 0) {
      throw Error("arguments cannot be empty!");
    }
    const param = [...arguments].slice(1);
    obj.myCall = this;
    let res = obj.myCall("engineer", "web");
    delete obj.myCall;
    return res;
  }
  Function.prototype.myCall = myCall;
  let res = sayName.myCall(obj, "engineer", "web");
  console.log(res); //hpf 24 engineer web

apply

参考apply的使用方法和call的手写,稍加改动即可轻松秒杀

  function myApply(obj) {
    if(arguments.length === 0) {
      throw Error("arguments cannot be empty!");
    }
    const param = arguments[1];
    obj.myApply = this;
    let res = obj.myApply("engineer", "web");
    delete obj.myApply;
    return res;
  }
  Function.prototype.myApply = myApply;
  let res = sayName.myApply(obj, ["engineer", "web"]);
  console.log(res); //hpf 24 engineer web

bind

参考bind的使用方法,单纯的调用myFunction.bind只是返回一个函数,因此略有不同

  function myBind(obj) {
    if (arguments.length === 0) {
      throw Error("arguments cannot be empty!");
    }
    const myFun = this;
    const param = [...arguments].slice(1);
    return function MyFun() {
      return myFun.apply(
        this instanceof MyFun ? this : obj,
        param.concat([...arguments])
      )
    }
  }
  Function.prototype.myBind = myBind;
  let res = sayName.myBind(obj)("engineer", "web");
  console.log(res); //hpf 24 engineer web
上一篇 下一篇

猜你喜欢

热点阅读