call,apply,bind实现+原理

call实现思路:

  • 1.判断当前this是否为函数,防止Function.prototype.myCall() 直接调用
  • 2.context 为可选参数,如果不传的话默认上下文为 window
  • 3.为context 创建一个 Symbol(保证不会重名)属性,将当前函数赋值给这个属性
  • 4.处理参数,传入第一个参数后的其余参数
  • 4.调用函数后即删除该Symbol属性
Function.prototype.myCall = function (context = window, ...args) {
      if (this === Function.prototype) {
        return undefined; // 用于防止 Function.prototype.myCall() 直接调用
      }
      context = context || window;
      const fn = Symbol();
      context[fn] = this;
      const result = context[fn](...args);
      delete context[fn];
      return result;
    }
/*
*  这三句的重点,是创建一个fn函数给context,这样context对象的fn就能使用context里的
*  上下文,然后执行fn函数,返回执行结果(也就等于调用对象可以使用context定义的内容)
*  本质还是this指向调用的对象
*  const fn = Symbol();
*  context[fn] = this;
*  const result = context[fn](...args);
*/

apply实现思路:和call差别在传参方式

 Function.prototype.myApply = function (context = window, args) {
      if (this === Function.prototype) {
        return undefined; // 用于防止 Function.prototype.myCall() 直接调用
      }
      const fn = Symbol();
      context[fn] = this;
      let result;
      if (Array.isArray(args)) {
        result = context[fn](...args);
      } else {
        result = context[fn]();
      }
      delete context[fn];
      return result;
    }

bind实现思路:详细参考https://juejin.cn/post/6844903633067180039

  • 1.处理参数,返回一个闭包
  • 2.判断是否为构造函数调用,如果是则使用new调用当前函数
  • 3.如果不是,使用apply,将context和处理好的参数传入
   Function.prototype.myBind = function (context,...args1) {
      if (this === Function.prototype) {
        throw new TypeError('Error')
      }
      const _this = this
      return function F(...args2) {
        // 判断是否用于构造函数
        if (this instanceof F) {
          return new _this(...args1, ...args2)
        }
        return _this.apply(context, args1.concat(args2))
      }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值