call,apply,bind 为何要叫作三兄弟,是由于他们有一个共同的父亲——Function.prototype,因此他们都是实例方法,不妨我们现场"滴血认亲"一下javascript
Function.prototype.hasOwnProperty('call');
Function.prototype.hasOwnProperty('apply');
Function.prototype.hasOwnProperty('bind');
复制代码
上面三条语句的返回结果都为true,算了有图有真相,上图java
所以,这三兄弟能够在对象,数组,函数中均可以使用。数组
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方法能够传递多个参数,第一个参数即为指定的this的指向,即要提供这个函数要执行所存在的做用域的家伙,后面的参数是函数调用时须要使用的参数,直接用","号分割便可。ui
若是 call的第一个参数为null或者undefined或者this,它等同于指向全局对象。this
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方法用于指定函数内部的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则是把做用域修改后的函数返回,须要本身再次手动调用。
从上面的例子咱们能够看到三兄弟十分类似,但也各有千秋。
同:
异: