apply

  1. Function.prototype.myCall = function (context, args = []) {
  2. // 判断调用该方法的对象是否是函数
  3. if (typeof this !== "function") {
  4. throw new TypeError(`It's must be a function`);
  5. }
  6. // context 不存在,或者传递的是 null undefined,则默认为 window
  7. context = context || window
  8. // 指定唯一属性,防止 delete 删除错误
  9. const fn = Symbol();
  10. // this 是调用 myCall 的函数
  11. context[fn] = this;
  12. // 调用 context 的 fn
  13. const result = context[fn](...args);
  14. // 删除掉 context 新增的属性
  15. delete context[fn];
  16. // 将结果返回
  17. return result;
  18. };

bind

bind() 会返回一个新函数

  1. Function.prototype.myBind = function (context, ...args) {
  2. const fn = this
  3. if (typeof fn !== 'function') {
  4. throw new TypeError('It must be a function')
  5. }
  6. context = context || window
  7. return function (...otherArgs) {
  8. return fn.apply(context, [...args, ...otherArgs])
  9. }
  10. }

call

apply() 第二个参数接收的是一个数组, call() 接收的是一个参数列表

  1. Function.prototype.myCall = function (context, ...args) {
  2. // 判断调用该方法的对象是否是函数
  3. if (typeof this !== "function") {
  4. throw new TypeError(`It's must be a function`);
  5. }
  6. // context 不存在,或者传递的是 null undefined,则默认为 window
  7. context = context || window
  8. // 指定唯一属性,防止 delete 删除错误
  9. const fn = Symbol();
  10. // this 是调用 myCall 的函数
  11. context[fn] = this;
  12. // 调用 context 的 fn
  13. const result = context[fn](...args);
  14. // 删除掉 context 新增的属性
  15. delete context[fn];
  16. // 将结果返回
  17. return result;
  18. };