在日常开发中,bind,call,apply这三个函数是使用率比较高的函数,它们都可以改变函数都执行作用域(改变this),那么我们知道它们是如何实现都吗,下面我们来手动实现以下这三个函数:

call,apply

根据MDN的描述,call 方法调用一个函数, 其具有一个指定的 this 值和分别地提供的参数。call 和 apply 的具体功能相同,唯一的区别是传参方式不一样。call 传参数是分开的,apply 是用一个组数传递参数。下面是这两个函数的具体实现:

  1. //call
  2. Function.prototype.call = function (context) {
  3. let context = context || window;
  4. context.fn = this;
  5. let args = [...arguments].slice(1);
  6. let result = context.fn(...args);
  7. delete context.fn
  8. return result;
  9. }
  10. //apply
  11. Function.prototype.apply = function (context, arr) {
  12. let context = Object(context) || window;
  13. context.fn = this;
  14. let result;
  15. if (!arr) {
  16. result = context.fn();
  17. } else {
  18. let args = [...arr].slice(1);
  19. result = context.fn(...args)
  20. }
  21. delete context.fn
  22. return result;
  23. }

bind

根据MDN描述,bind 方法创建一个新的函数,在调用时设置 this 关键字为提供的值。并在调用新函数时,将给定参数列表作为原函数的参数序列的前若干项。

  1. //bind
  2. Function.prototype.bind = function (context) {
  3. if (typeof this !== "function") {
  4. throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
  5. }
  6. let self = this;
  7. let args = [...arguments].slice(1);
  8. return function F() {
  9. if (this instanceof F) {
  10. return new _self(...args,...arguments);
  11. }
  12. return _self.apply(context,[...args,...arguments]);
  13. }
  14. }