JS中this的指向

2019-09-25  本文已影响0人  zooeydotmango

在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:'饥人谷'}))
上一篇下一篇

猜你喜欢

热点阅读