在JavaScript中,this的动态切换使变成变得模糊和困难。call, apply, bind 都是Function对象自带的方法,其作用在于切换/固定this的指向。
- Function.prototype.call
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。
call() 可以指定函数内部this的指向,在其所指定的作用域中,调用该函数;call方法的参数应该是一个对象,如果参数为空,null,undefined,则默认传入全局对象。
var n = 123;
var obj = { n: 456 };
function a() {
console.log(this.n);
}
a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456
call可以用来调用对象的原生方法。
var obj = {};
obj.hasOwnProperty('toString') // false
// 覆盖掉继承的 hasOwnProperty 方法
obj.hasOwnProperty = function () {
return true;
};
obj.hasOwnProperty('toString') // true
Object.prototype.hasOwnProperty.call(obj, 'toString') // false
- Funciton.prototype.apply()
apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。
apply方法的作用与call方法类似,也是改变this指向,然后再调用该函数。唯一的区别就是,它接收一个数组作为函数执行时的参数.其使用格式为:
func.apply(thisValue, [arg1, arg2, ...])
apply方法的第一个参数也是this所要指向的那个对象,如果设为null或undefined,则等同于指定全局对象。第二个参数则是一个数组,该数组的所有成员依次作为参数,传入原函数。
function f(x, y){
console.log(x + y);
}
f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2
- Function.prototype.bind()
bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
bind方法的参数就是所要绑定this的对象:
var counter = {
count: 0,
inc: function () {
this.count++;
}
};
var func = counter.inc.bind(counter);
func();
counter.count // 1
如果bind方法的第一个参数是null或undefined,等于将this绑定到全局对象,函数运行时this指向顶层对象
function add(x, y) {
return x + y;
}
var plus5 = add.bind(null, 5);
plus5(10) // 15