js的this指向之显示绑定

209 阅读1分钟

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);