(回顾)JS中call和apply和bind这三个函数区别、原生JS实现bind()方法、arguments含义

call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:(https://www.runoob.com/w3cnote/js-call-apply-bind.html

  • call 的参数是直接放进去的,第二到第n个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。
  • apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。
  • bind 除了返回是函数以外,它 的参数和 call 一样。

 

https://www.jianshu.com/p/7030376af23c

一、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函数的方式

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值