在ES5中this 永远指向最后调用它的那个对象,在箭头函数中this指向定义时所在的对象。
this的本质
JS中三种调用函数的形式:
func(p1, p2)
obj.child.method(p1, p2)
func.call(context, p1, p2)
都可以归根为第三种形式
func.call(context, p1, p2)
当我们使用func()
时没有指定context,浏览器会遵循规则:
如果你传的 context 就 null 或者 undefined,那么 window 对象就是默认的 context(严格模式下默认 context 是 undefined)
如果需要改变context,在call中传入:
obj.foo.call(obj) //this指向obj
事件监听器中的this
btn.addEventListener('click' ,function handler(){
console.log(this) // 请问这里的 this 是什么
})
当事件触发时,handler中实际上调用了
handler.call(event.currentTarget, event);
//所以this指向event.currentTarget
jQuery中监听器的this
jQuery文档:
当jQuery的调用处理程序时,this关键字指向的是当前正在执行事件的元素。对于直接事件而言,this 代表绑定事件的元素。对于代理事件而言,this 则代表了与 selector 相匹配的元素。(注意,如果事件是从后代元素冒泡上来的话,那么 this 就有可能不等于 event.target。)若要使用 jQuery 的相关方法,可以根据当前元素创建一个 jQuery 对象,即使用 $(this)。
箭头函数的this值
箭头函数中this指向定义时所在的对象
var app = {
fn1() {
setTimeout(function(){
console.log(this)
}, 10)
},
fn2() {
setTimeout(()=>{
console.log(this)
},20)
},
fn3() {
setTimeout((function(){
console.log(this)
}).bind(this), 30)
},
fn4: ()=> {
setTimeout(()=>{
console.log(this)
},40)
}
}
以fn4为例,40ms后调用()=>{console.log(this)}
中this指向fn4中的this,也就是App,但fn4本身也是箭头函数,所以fn4中this还要找App定义时所在对象也就是windows。
以此我们可以得出简单结论
所以如果你在箭头函数里面看到 this ,就当作是它外面的函数的 this 即可。
如何改变this的指向
自己写call/apply:
function handlerWrapper(event){
function handler(){
console.log(this) // 请问这里的 this 是什么
}
handler.call({name:'饥人谷'}, event)
}
btn.addEventListener('click', handlerWrapper)
或者使用bind,bind后返回的是一个函数名
btn.addEventListener('click', function(){
console.log(this) // 请问这里的 this 是什么
}.bind({name:'饥人谷'}))
网友评论