首先先明白一个定义:this是指对当前对象的引用
案例
对于如下结构
<body>
<h1>Hello ECMAS cript</h1>
<button id="btn">点我</button>
<script src="static/2-1.js"></script>
</body>
代码1
let oBtn = document.querySelector('#btn');
oBtn.addEventListener('click',function(){
console.log(this);
})
this指的是对当前对象的引用,btn绑定的click事件,所以当前引用应该是btn
当点击按钮时,会看到
代码2
现在有一个定时器,希望点击后一秒再输出this,我们根据该需求编写如下代码:
let oBtn = document.querySelector('#btn');
oBtn.addEventListener('click',function(){
setTimeout(function(){
console.log(this);
},1000)
})
当点击按钮时,会看到
可以看到this指向了window,说明当前对象是window,指的是调用的对象,setTimeout是window的一个方法,即上述代码与window.setTimeout(function(){ console.log(this); },1000)
等价,所以setTimeout里面的this就指向了window
代码3
但是我们想要获取到obtn对象,在ES5里有3个方法可以改变this指向:即 call apply 和bind。这里使用bind (因为all和apply会让该方法马上执行)。bind里的参数表示希望当前里面的这个作用域指向谁,bind里的参数就写它。(bind里的this指的是oBtn,传递进去后,setTimeout的this就指的是obtn)
let oBtn = document.querySelector('#btn');
oBtn.addEventListener('click',function(){
setTimeout(function(){
console.log(this);
}.bind(this),1000)
})
当点击按钮后,打印出
捋一下上面的关系:
代码4
除了使用bind函数改变了this指向,我们还可以使用ES6的箭头函数,代码如下:
let oBtn = document.querySelector('#btn');
oBtn.addEventListener('click',function(){
console.log(this);
setTimeout(()=>{
console.log(this);
},1000)
})
这时的this指向button,因为在箭头函数里,this指向定义时所在的对象,而不是调用时所在的对象(其实箭头函数里面并没有this,箭头函数里的this是继承了箭头函数外的执行环境里的this),所以往setTimout里面的this是找到了外面的oBtn。