zoukankan      html  css  js  c++  java
  • javascript中bind()、call()、apply()的使用

    一直以来对bind()、apply()、call()这三个方法都模模糊糊的,现在有时间详细的看看这三个方法,并记录下来。

    bind()

    参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

    • 定义:

    bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

    • 用法:

    func.bind(thisArg, arg1, arg2, ...)

    var obj = {
      a: 1,
      b: 2,
      getCount: function(c, d) {
        return this.a + this.b + c + d;
      }
    };
    window.a = window.b = 0;
    var func1 = obj.getCount;
    var func2 = obj.getCount.bind(obj);
    console.log(func1(3, 4));//得到7
    console.log(func2(3, 4));//得到10
    • 说明:

    bind()是Function的一个方法,所以应该是一个a函数来调用bind,参数是可以有若干个如(d,e,f),调用了bind方法后会返回一个新的方法b,b = a.bind(c,d,e,f),新函数b调用时,实际调用的却是a,但this指针指向的的却是c,d,e,f会作为参数带到a函数里面;
    在上例中,func1之所以得到7是因为func1的this指向的是window,func2调用时this指向的是obj,所以得到10。

    • 示例:
    1. 创建绑定函数(如上例):
       (function() {
          console.log(this.a);
      }.bind({
          a: 10
      }))()//输出10
      (function() {
          console.log(this.a);
      })()//输出undefined
    2. 偏函数:创建一个调用另一个部分——参数或变量已经预置的的函数——的函数的用法(拗口,看示例吧),说白了就是让一个函数拥有预设的初始参数
      //例1
      function list() {
        return Array.prototype.slice.call(arguments);
      }
      var list1 = list(1, 2, 3); // [1, 2, 3]
      var leadingThirtysevenList = list.bind(undefined, 37);//37作为list的预设的初始参数
      var list2 = leadingThirtysevenList(); // [37]
      var list3 = leadingThirtysevenList(1, 2, 3); // [37, 1, 2, 3]
      //例2
      function joinWords(a,b) { 
      	return [a,b].join(' '); 
      }
      //不使用bind
      function prefixer(word) {
      	return function(b) { 
      		return joinWords(word,b);
      	}
      }
      var prefixWithHate = prefixer('Hate');
      console.log(prefixWithHate('Java'));//Hate Java
      //使用bind
      var prefixWithHate2 = joinWords.bind(window,"Hate");
      console.log(prefixWithHate2('Java'));//Hate Java
    3. 配合 setTimeout:如何用setTimeout连续打印0~9
      for(var i = 0; i < 10; i++) {//不使用bind
        (function(i) {
          setTimeout(function() {
            console.log(i);
          }, i * 1000);
        })(i);
      }
      for(var i = 0; i < 10; i++) {//使用bind
        setTimeout(console.log.bind(null, i), i * 1000);//给了console.log一个默认的参数i
      }

    apply()、call()

    参考文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

    • 定义:

    apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。
    call() 方法调用一个函数, 其具有一个指定的this值,以及分别地提供的参数(参数的列表)。

    • 用法:

    fun.apply(thisArg, [argsArray])
    fun.call(thisArg, arg1,arg2,arg3,...)

    • 说明:

    fun调用apply方法是这样fun里面的this指针指向thisArg,[argsArray]是一个数组或是类数组(arguments)作为fun函数的参数;
    call方法除了参数和apply不一样其他都相同。

    • 示例:
    1. 使用call/apply实现继承:
      function a1(b){
        this.b = b;
        this.c = function(){
        	console.log(this.b);
        }
      }
      function a2(b){
        a1.apply(this,[b]);
        //a1.call(this,b);
      }
      
      var a3 = new a2(123);
      a3.c();//打印出123
    2. 使用apply和内置函数
      //得到最大值、最小值
      var arr = [5,6,9,11,0,1,3];
      var max = Math.max.apply(null,arr);
      var min = Math.min.apply(null,arr);
      console.log(max,min)//得到11,0

    bind()、aplly()和call()的区别:

    • 返回值不同:调用bind()返回一个新的函数,aplly()和call()返回调用这两个方法的函数的返回值,如:
    function add(a,b){
        return a + b;
    }
    function sub(a,b){
        return a - b;
    }
    var a1 = add.bind(sub,3,2);
    var a2 = add.apply(sub,[3,2]);
    var a3 = sub.call(add,3,2);
    console.log(a1,a1(),a2,a3);//得到的是:ƒ add(a,b){return a + b;},5,5,1
    • 参数不同:bind()和call()的参数结构相同,都是this的新指向和一串参数,apply()的参数是this的新指向加一个数组或是类数组;
  • 相关阅读:
    jstl表达式判断字符or字符串相等的写法
    enctype="multipart/form-data导致request获取不到数据
    Mac下解决mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    单源文件目录makefile
    默认生成的特殊函数
    为什么说switch比if快
    C++基本内置类型
    补码的原理及其应用
    CSS--浮动与定位
    CSS--字体
  • 原文地址:https://www.cnblogs.com/hl1223/p/8317591.html
Copyright © 2011-2022 走看看