美文网首页this
JS bind()方法、JS原生实现bind()

JS bind()方法、JS原生实现bind()

作者: web_jianshu | 来源:发表于2020-06-28 12:43 被阅读0次

    一、arguments的含义

     // arguments 是一个对应于传递给函数的参数的类数组对象
          function a() {
            console.log(arguments);
          }
          a(); // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
          a(1, 2, 3); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    

    二、Function.prototype.bind()

    bind()方法主要就是将函数绑定到某个对象,bind()会创建一个函数,函数体内的this对象的值会被绑定到传入bind()中的第一个参数的值,例如:f.bind(obj),实际上可以理解为obj.f(),这时f函数体内的this自然指向的是obj;

     var a = {
            b: function() {
              var func = function() {
                console.log(this.c);
              };
              func();
            },
            c: "hello"
          };
          a.b(); // undefined 这里的this指向的是全局作用域
          console.log(a.c); // hello
    
     var a = {
            b: function() {
              var _this = this; // 通过赋值的方式将this赋值给that
              var func = function() {
                console.log(_this.c);
              };
              func();
            },
            c: "hello"
          };
          a.b(); // hello
          console.log(a.c); // hello
    
     // 使用bind方法一
          var a = {
            b: function() {
              var func = function() {
                console.log(this.c);
              }.bind(this);
              func();
            },
            c: "hello"
          };
          a.b(); // hello
          console.log(a.c); // hello
    
          // 使用bind方法二
          var a = {
            b: function() {
              var func = function() {
                console.log(this.c);
              };
              func.bind(this)();
            },
            c: "hello"
          };
          a.b(); // hello
          console.log(a.c); // hello
    
     // 分析:这里的bind方法会把它的第一个实参绑定给f函数体内的this,所以里的this即指向{x:1}对象;
          // 从第二个参数起,会依次传递给原始函数,这里的第二个参数2即是f函数的y参数;
          // 最后调用m(3)的时候,这里的3便是最后一个参数z了,所以执行结果为1+2+3=6
          // 分步处理参数的过程其实是一个典型的函数柯里化的过程(Curry)
          function f(y, z) {
            return this.x + y + z;
          }
          var m = f.bind({ x: 1 }, 2);
          console.log(m(3)); // 6
    
     // 分析:直接调用a的话,this指向的是global或window对象,所以会报错;
          // 通过bind或者call方式绑定this至document对象即可正常调用
          var a = document.write;
          a("hello"); // error
          a.bind(document)("hello"); // hello
          a.call(document, "hello"); // hello
    
    // 实现预定义参数
          // 分析:Array.prototype.slice.call(arguments)是用来将参数由类数组转换为真正的数组;
          function list() {
            return Array.prototype.slice.call(arguments);
          }
          var list1 = list(1, 2, 3); // [1,2,3]
          // 第一个参数undefined表示this的指向,第二个参数10即表示list中真正的第一个参数,依次类推
          var a = list.bind(undefined, 10);
          var list2 = a(); // [10]
          var list3 = a(1, 2, 3); // [10,1,2,3]
    

    三、原生js实现bind方法

    // 方法一,只可绑定,不可传参
          Function.prototype.my_bind = function(context) {
            var self = this;
            return function() {
              self.apply(context, arguments);
            };
          };
          function a() {
            console.log(this.name);
          }
          a(); // ''
          var b = {
            name: "apple"
          };
          a.bind(b)(); // apple
          a.my_bind(b)(); // apple
    
      Function.prototype.my_bind = function() {
            var self = this, // 保存原函数
              context = Array.prototype.shift.call(arguments), // 保存需要绑定的this上下文
              // 上一行等价于 context = [].shift.call(arguments);
              args = Array.prototype.slice.call(arguments); // 剩余的参数转为数组
            return function() {
              // 返回一个新函数
              self.apply(
                context,
                Array.prototype.concat.call(
                  args,
                  Array.prototype.slice.call(arguments)
                )
              );
            };
          };
    
          function a(m, n, o) {
            console.log(this.name + " " + m + " " + n + " " + o);
          }
          var b = {
            name: "kong"
          };
          a.my_bind(b, 7, 8)(9); // kong 7 8 9
    

    JS中的bind()方法
    js中自己实现bind函数的方式

    相关文章

      网友评论

        本文标题:JS bind()方法、JS原生实现bind()

        本文链接:https://www.haomeiwen.com/subject/wjnifktx.html