1、call、bind、apply 都是用来干什么的?
call、bind、apply都是用来改变this指向的
2、他们之间的区别是什么?
2.1 call方法
可以指定该函数内部this的指向,然后在所指定的作用域中,调用该函数,并且会立即执行该函数。
call的使用方法:
function keith(a, b) {
return a+b;
}
keith.call(null, 1 , 2); // 3
call有两个参数,第一个参数必需,用来制定this指向,第二个是函数调用时需要传递的参数,必需一个个的添加。
call的执行过程:
1、把找到的call方法执行,当call方法执行的时候,内部处理了一些事情
2、首先把要操作的函数中的this关键字变为call方法第一个传递的实参
3、把call方法第二个及之后的实参获取到
4、把要操作的函数执行,并且把第二个以后传递进来的实参传递给函数
var keith = {
rascal: 123
};
var rascal = 456;
function a() {
console.log(this.rascal);
}
a(); //456
a.call(); //456
a.call(null); //456
a.call(undefined); //456
a.call(this); //456
a.call(keith); //123
a函数中的this关键字,如果指向全局对象,返回结果为456。可以看到,如果call方法没有参数,或者参数为null或undefined或者this,则等同于指向全局对象。如果使用call方法将this关键字指向keith对象,也就是将该函数执行时所在的作用域为keith对象,返回结果为123。
2.2 apply方法
apply与call唯一不同的一点是:第二个参数必须以数组的形式添加
function keith(a, b) {
return a+b;
}
keith.call(null, 1 , 2); // 3
keith.apply(null, [1,2]); // 3
2.3 bind方法
bind与call不同的一点是:bind改变this指向,并返回一个新函数,bind方法不会立即执行。
var keith = {
a: 1,
count: function() {
console.log(this.a++);
}
};
keith.count(); //1
keith.count(); //2
keith.count(); //3
上面的例子中,this.a指向的是keith,所以每调用一次,a的值都会+1;但如果把keith.count赋值给另外一个变量时,调用就会出错,例如:
var keith = {
a: 1,
count: function() {
console.log(this.a++);
}
};
f = keith.count;
f(); // NaN
这个例子中,keith.count赋值给f,那么this指向的不再死Keith了,而是window对象,window.a是undefined,undefined++就会变成NaN。 为了解决这个问题,可以使用bind方法,将keith对象里的this绑定到keith对象上,或者是直接调用。
var f = keith.count.bind(keith);
f(); //1
f(); //2
f(); //3
或者绑定到别的对象上:
var obj = {
a: 100
};
var f = keith.count.bind(obj);
f(); //100
f(); //101
f(); //102
综上:
function keith(a, b) {
return a + b;
}
console.log(keith.apply(null,[1,4])); //5
console.log(keith.call(null,1,4)); //5
console.log(keith.bind(null, 1, 4)); //keith()
console.log(keith.bind(null, 1, 4)()); //5
可以看出call,apply,bind三者的区别:call和apply方法都是在调用之后立即执行的。而bind调用之后是返回原函数,需要再调用一次才行。call和bind的参数是一个个添加进去,而apply是使用数组一次性添加