JavaScript--自定义bind函数

本文介绍了JavaScript中的bind函数,它是柯理化思想的体现,通过创建闭包保存预先准备好的信息。文章还详细阐述了如何实现bind函数,并提供了代码示例,邀请读者分享更多实现思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bind函数介绍

bind函数实际上是柯理化思想。大函数执行返回一个小函数,执行大函数,把需要准备的内容准备好、当前大函数的执行上下文因为小函数的引用关系就不能销毁了,形成了闭包。这样事先准备好的内容就能保存下来,当执行小函数时就会用到大函数里保存的信息。
这相当于大函数预先把信息存储起来,以后用的时候直接在小函数中调用即可。

实现bind函数

  1. 最外围是一个立即执行函数,在立即执行函数中完成使用自定义bind替换Function.prototype.bind。直接上代码喽,讲解写在注释中。
     // 如果让我们自己实现一个bind,该怎么写呢
    ~function anonymous(proto){
      /**
      ** context
      */
      function bind(context) {
        // bind 中的 this =>(指向)需要最终执行的函数 
        //js中 null == undefined, 不传参也是undefined。所以null、undefined、null都可以用是否==undefined 判断
        if (context == undefined) { // 给context一个默认值
          context = window; 
        }
        // 拿其余的参数: arguments 是类数组,我们借用数组的方法来处理
        var args = [].slice.call(arguments, 1); // 第一个参数是context.相当于 Array.prototype.slice.call(arguments, 1);
        
        var _this = this; // 需要执行的函数

        // bind需要返回一个新的函数,这个新的函数中需要执行 _this 函数
        // 牵涉到事件处理时,这个匿名函数中还需要传参数,比如时间对象ev
        return () => {
          var innerArgs = [].slice.call(arguments, 0);
          _this.apply(context, args.concat(innerArgs));
        }
        
      }
      proto.bind = bind; // Function原型中的bind替换为我们自己的
    }(Function.prototype);
  1. 上面是老语法啦,怎么利用es6的语法来实现呢?顺便给出call函数的实现思路。
    // es6语法重写自定义bind
    ~function(proto) {
      function bind(context = window, ...outerArgs) {
        // 经过测试,apply 传递多个参数时,性能不如call
        return (...innerArgs) => {
          
          this.call(context, ...outerArgs.concat(innerArgs)); // 箭头函数中的this是外围执行上下文中的this
        };
      }
      
      function call(context = window, ...args) {
        // 必须保证context 是引用类型,不能是基本类型
        context === null ? context = window:null;
        let type = typeof context;
        if (type !== 'object' && type !== 'function' && type != 'symbol') { // 基本类型
          switch(type) {
            case 'number':
              context = new Number(context);
              break;
            case 'boolean':
              context = new Boolean(context);
              break;
            case 'string':
              context = new String(context);
              break;
          }
        }
        context.$fn = this;
        let result = context.$fn(...args);
        delete context.$fn;
        return result;
      }

      proto.bind = bind;
      proto.call = call;
    }(Function.prototype);

至此,全文结束。欢迎大家给出更合理的实现思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值