1. call

call 方法使用一个指定的 this值和单独给出的一个或多个参数来调用一个函数.

function.call(thisArg, arg1, arg2…)

  1. // 重写call
  2. /*
  3. call 方法作用:
  4. 1. 改变this的指向, 指向到call的值
  5. 2. 函数执行
  6. */
  7. Function.prototype.myCall = function (context) {
  8. // 1. 获取参数, 第一项this指向不要
  9. var args = Array.prototype.slice.call(arguments, 1);
  10. let result = null;
  11. // 2.判断是否传入 上下文, 没有则指向window
  12. context = context || window;
  13. // 3. 将调用的方法挂载到 context,
  14. context.fn = this;
  15. // 执行要调用的方法
  16. result = context.fn(...args);
  17. // 从上下文中删除添加的 属性方法
  18. delete context.fn;
  19. // 返回结果
  20. return result
  21. }

2. apply

apply call唯一的区别是, apply的参数使用数组进行传递.

  1. Function.prototype.myApply = function (context) {
  2. var result = null;
  3. context = context || window;
  4. const fnSymbol = Symbol();
  5. context[fnSymbol] = this;
  6. result = context[fnSymbol](...arguments[1]);
  7. delete context[fnSymbol];
  8. return result;
  9. }

3. bind

bind 改变 this指向, 返回一个新的函数, 但是不执行.
bind挂载在 Function.prototype
new过bind返回的函数, this指向失效.

  1. Function.prototype.bindy = function (context) {
  2. var _self = this;
  3. var args = Array.prototype.slice.call(arguments, 1);
  4. var tempFn = function () {};
  5. var fn = function () {
  6. var newArgs = Array.prototype.slice.call(arguments);
  7. // new -> this -> fn{} -> __proto__ -> Person
  8. // no new -> window
  9. _self.apply(this instanceof _self ? this : context, args.concat(newArgs));
  10. }
  11. // 圣杯模式
  12. tempFn.prototype = this.prototype;
  13. fn.prototype = new tempFn();
  14. return fn;
  15. }