Call,Apply与Bind的兄弟密谈

三兄弟来源

call,apply,bind 为何要叫作三兄弟,是由于他们有一个共同的父亲——Function.prototype,因此他们都是实例方法,不妨我们现场"滴血认亲"一下javascript

Function.prototype.hasOwnProperty('call'); 
Function.prototype.hasOwnProperty('apply');
Function.prototype.hasOwnProperty('bind');
复制代码

上面三条语句的返回结果都为true,算了有图有真相,上图java

FUddkF.png

所以,这三兄弟能够在对象,数组,函数中均可以使用。数组

大哥——Call

call方法,能够指定所用目标函数的this指向,即函数执行时所在的做用域(上下文),而且在指定的做用域调用这个函数,当即执行。app

var content = {
    number: 2
};

var number = 1;

function func(){
    console.log(this.number);
}
a();  //结果为1
a.call(); //没有传递参数仍是默认所在的做用域
a.call(content); //指向content的内部做用域,此时结果为2

复制代码

即,当咱们执行a函数时,它指向的是全局对象,因此this指向的也就是全局对象;但当咱们帮它指向content对象时,这个函数的执行做用域也就变为了content对象的做用域函数

Call 传参

call方法能够传递多个参数,第一个参数即为指定的this的指向,即要提供这个函数要执行所存在的做用域的家伙,后面的参数是函数调用时须要使用的参数,直接用","号分割便可。ui

若是 call的第一个参数为null或者undefined或者this,它等同于指向全局对象。this

二哥——Apply

apply方法身为二哥,天然是和大哥的做用很是类似,他们都是改变this指向来在制定的做用域中调用这个函数,当即执行,惟一的不一样可能就是二哥Apply相比较于大哥Call来讲它更"挑食"。它只能接收两个参数,第一个参数为this指向的对象,第二个参数为执行时须要的参数,注意,它只要数组做为他的第二个参数。spa

咱们让大哥和二哥实现相同的功能来看一下他们的不一样prototype

function sum(a,b){
    return a + b;
}
sum.call(this,1,2); //结果为3
sum.apply(this,[1,2]); //结果为3
复制代码

因此,当咱们要让某个数组来执行某种方法时,使用apply方法相较于call方法能方便不少。好比咱们想快速的查找一个数组中的最大值code

var a = [1,2,3,4,5,7,8,9,45,123,111];
Math.max.apply(this,a); // 123
复制代码

三弟——bind

bind方法用于指定函数内部的this指向,而后返回一个新函数,但它不会当即执行,它只是给这个函数增长了修饰,并无调用它。

var content = {
    number: 2
};

function func(){
    console.log(this.number);
}

//call方法
func.call(content); // 2
//apply方法
func.apply(content); //2
//bind方法
func.bind(content)(); //2
复制代码

bind的参数要求和大哥同样,即为一个一个的传参.

call 和 apply 方法在调用后会当即执行,而bind则是把做用域修改后的函数返回,须要本身再次手动调用。

三兄弟异同

从上面的例子咱们能够看到三兄弟十分类似,但也各有千秋。

同:

  • 都用来改变函数的this指向,即做用域。
  • 第一个参数都是用来指定函数内部的this。
  • 均可以在函数调用的时候传递原函数所须要的参数。

异:

  • call 和 apply 调用后当即执行,而bind则是把新函数返回,须要再次调用。
  • call 和 bind 传递参数是直接传入,也就是一个一个的传,而apply 则须要一个数组来做为第二个参数。
相关文章
相关标签/搜索