先看一个栗子:
var name = 'from window';
var obj = {
name: 'from obj',
func: function(){
setInterval(function () {
console.log(this.name)
},1000)
}
}
obj.func()
输出结果:"from window"
在setInterval
和setTimeout
中,如果回调函数是普通函数并且this没有特别指向,那么回调中的this默认指向window。
但是一般在开发中,很多场景都需要改变this的指向。以下三中方式可以修改回调中this的指向。
1、最常用的方法:在外部函数中将this存为一个变量,在回调函数中使用变量,而不是直接使用this。
var name = 'from window';
var obj = {
name: 'from obj',
func: function(){
var _this = this;
setInterval(function () {
console.log(_this.name)
},1000)
}
}
obj.func()
输出结果: from obj
2、使用es6中的bind()方法修改函数中this的指向。
bind()和call()/apply()的作用一样,都可以修改函数内部this的指向,但是call和appll用于修改this指向后立即执行函数的,而bind则是返回一个新的函数,它会创建一个与原来函数体相同的新函数,新函数中的this指向传入的对象。如果接触过react,这下就知道在类组件的类构造函数constructor中为什么经常会见到this.click = this.click.bind(this)
这种写法了。
var name = 'from window';
var obj = {
name: 'from obj',
func: function(){
setInterval(function () {
console.log(this.name)
}.bind(this),1000)
}
}
obj.func()
输出结果: from obj
这里不使用call和apply的原因是call、apply不会返回新函数,而是调用函数时立即使用。
3、使用es6的箭头函数:箭头函数的最大作用就是this指向。
var name = 'from window';
var obj = {
name: 'from obj',
func: function(){
setInterval(()=>{
console.log(this.name)
},1000)
}
}
obj.func()
输出结果: from obj
箭头函数没有自己的this
,它的this
继承自外部函数的作用域。所以定时器回调中的this
指向func函数中的this
,又因为func由obj调用,所以func中的this指向obj。