1.用call(),apply()改变this指向
call(),apply()的第一个参数可以指定this的绑定对象,为空则默认绑定window
var a = 0;
function fn(){
console.log(this.a);
}
var obj = {
a: 1
}
fn(); // 0 --> this默认指向window
fn.call(obj); // 1 --> this指向直接对象obj
fn.apply(obj); // 1 --> this指向直接对象obj
2.硬绑定
绑定后就不能二次更改绑定对象,一次绑定永久有效
/*
示例1---call()硬绑定
*/
var a = 0;
function fn(){
console.log(this.a);
}
var obj = {
a: 1
}
var bar = function(){
// 这里代码已进入就强行改变绑定对象
fn.call(obj);
}
bar(); // 1 --> this绑定对象已改变成obj
setTimeout(bar, 2000); // 2秒后显示1 --> 一次绑定永久有效,此时this的绑定对象依然是obj
bar.call(window); // 1 --> 试图改变this的绑定对象,但是无法改变,this的绑定对象依然是obj
/*
示例2---bind()硬绑定
*/
var a = 0;
function fn() {
console.log(this.a);
}
var obj = {
a: 1
}
var bar = fn.bind(obj);
bar(); // 1 --> 使用bind()后this绑定对象已改变成obj
bar.call(window); // 1 --> 硬绑定后无法二次更改绑定对象,这里this绑定对象已依旧是obj
3.一些函数(除call、apply、bind外)的某个参数能改变绑定对象
- forEach()
- map()
- filter()
- some()
- every()
- ...
var obj = {
id:'fn'
}
var arr = [1,2,3];
arr.forEach(function(el, index) {
// 这里this指向window
console.log(el, index, this);
});
arr.forEach(function(el,index){
// 这里this指向obj
console.log(el,index,this);
},obj);