js中的this指向

91 阅读2分钟

最近对js的this指向问题挺感兴趣,今天就把this指向的所有情况罗列下。

1. 最普通的函数

const obj = {
    age: 1,
    say() {
        console.log(this.age)
    }
}
obj.say() // 1
obj.say.bind({age: 2}) // 2,bind会改变this指向

2. 箭头函数

const obj = {
    age: 1,
    say: () => {
        console.log(this.age)
    }
}
obj.say() // undefined

babel官网转换后,变成下面的代码

var _this = this;
var obj = {
    age: 1,
    say: function say() {
        console.log(_this.age);
    }
};
obj.say() // undefined,说明this是window

3. 普通函数里返回箭头函数

const obj = {
    age: 1,
    say() {
       return () => {
           console.log(this.age)
       }
    }
}
obj.say()() // 1
obj.say.bind({ age: 2 })()() // 2
obj.say().bind({ age: 2 })() // 1

babel官网转换后,变成下面的代码

var obj = {
  age: 1,
  say: function say() {
    var _this = this;
    return function () {
      console.log(_this.age);
    };
  }
};
obj.say()() // 1
obj.say.bind({ age: 2 })()() // 2
obj.say().bind({ age: 2 })() // 1,说明不受箭头函数调用者影响

3. setTimeout普通函数

const obj = {
    age: 1,
    say() {
        setTimeout(function() {
            console.log(this.age)
        })
    }
}
obj.say() // undefined,this是window

4. setTimeout箭头函数

const obj = {
    age: 1,
    say() {
        setTimeout(()=> {
            console.log(this.age)
        })
    }
}
obj.say() // 1
obj.say.bind({ age: 2 })() // 2

babel官网转换后,变成下面的代码

var obj = {
  age: 1,
  say: function say() {
    var _this = this;
    setTimeout(function () {
      console.log(_this.age);
    });
  }
};
obj.say(); // 1
obj.say.bind({ age: 2 })(); // 2

结论

普通函数里this指向调用者
箭头函数里的this指向的是定义该箭头函数时所在作用域中的this,而不是执行该箭头函数时所在的作用域中的this
setTimeout普通函数指向window

参考文档

从这两套题,重新认识JS的this