天天看点

call、apply、bind的区别及使用语法三个语法相同点Object参数示例讲解不同点apply示例用途

语法

函数.apply(Object对象,[数组])

函数.call(Object,a1,a2,a3…)

函数.bind(Object,a1,a2,a3…)

三个语法相同点

call、apply、bind都是被一个函数调用;

Object参数:改变该函数的this对象

除Object参数外的其他参数(数组或者a1…):该函数所需要的参数

Object参数示例讲解

定义一个fn函数

var fn= function(a,b,c){
	console.log(this);
	console.log(a);
	console.log(b);
	console.log(c);
}
           

如果直接调用函数fn(1,2,3),控制台运行结果如下:

Window {}
1
2
3
           

如果调用函数fn.apply(1,[2,7,9]); ,控制台运行结果如下:

Number {1}
2
7
9
           

经过上述两次调用结果的比较,你会发现console.log(this)代码输出的this值改变了,由window对象变成了Number对象,所以验证了Object参数是改变被执行函数的this对象 (call、bind方法中参数Object也是同样的作用)

不同点

  • 函数.apply(Object对象,[数组])

    apply第二个参数必须是一个数组,当传入函数时,会被扩展成多个参数。 扩展:类似与ES6语法中的…arr

    比如上述执行函数 fn.apply(1,[2,7,9]),数组[2,7,9]就会扩展成多个参数2,7,9分别赋值给fn(a,b,c)方法中的a,b,c

  • 函数.call(Object对象, a1,a2,a3)

    相比apply,a1,a2,a3不可传数组进行扩展

  • 函数.bind(Object,a1,a2,a3…)

    执行完bind函数,返回的是绑定this以及参数的被执行函数

    • 示例讲解

      在控制台上执行bind函数且将结果赋值给bindfn

      var bindfn = fn.bind(1,8,9,10)
                 
      在控制台打印bindfn ,控制台运行结果如下:
      ƒ (a,b,c){
        	console.log(this);
        	console.log(a);
        	console.log(b);
        	console.log(c);
      }
                 

      从结果可看到:执行完bind函数,返回的是一个和fn一样的函数。

      然后再在控制台执行bind函数返回的函数bindfn如下代码:

      bindfn(2,5,7,6)
                 
      控制台运行结果为:
      Number {1}
      8
      9
      10
                 
      从结果看出,输出的值并非是Number {2} 5 7 6,而是执行fn.bind(1,8,9,10) 代码时传进的参数,由此验证了:【执行完bind函数,返回的是绑定this以及参数的被执行函数】,即使以不同的参数再次调用该返回函数bindfn,执行结果也不会改变。

apply示例用途

  1. 求数组[3,5,7,1,6]中的最大值:

    我们知道执行

    Math.max(3,5,7,1,6)
               
    执行完得到最大值7。但现在要传入数组,则使用apply得到最大值
    Math.max.apply(null,[3,5,7,1,6] )
               
  2. 类的继承:使用apply可以实现类的继承,如下所示

    现创建Animal类、Dog类,Dog类继承Animal类

    var Animal = function(name){
    	this.name = name;
      	console.log(this);
      	console.log(this.name);
    }
    var Dog = function(name,color){
        Animal.apply(this,arguments);
    }
               

    注:Animal.apply(this,arguments);此句代码中,

    this指代Dog类,

    arguments数组是所有(非箭头)函数中都可用的局部变量,代表传入的参数集合

    然后我们创建一个dog对象 【注:此时的arguments为: Arguments(2) [“dog name”, “orange”]】

    var dog1 = new Dog("dog name",'orange');
               
    控制台运行结果如下:
    Dog {name: "dog name"}
    dog name
               
    由此看出Dog类继承了Animal类的属性以及方法。

继续阅读