这里是文章模块栏目内容页
JS bind()方法、JS原生实现bind()
一、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 = [removed];
  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函数的方式



作者:puxiaotaoc
链接:https://www.jianshu.com/p/7030376af23c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


更多栏目
相关内容