无论是工作还是面试,this指向问题都经常遇到。所以本文列出了大家常见的指点问题,以免踩坑。首先我们要知道函数中this的值是在函数真正被调用执行的时候确定的,不能在定义函数的时候就确定的。也就是说,this的方向完全取决于函数调用的位置。因为this的值是作用域环境的一部分,每次调用函数时,都会在不同的作用域环境中。1:在全局环境下,在浏览器环境的严格模式下(区别于node),this默认指向window。立即执行函数,默认定时器等函数,这个也指向window。console.log(this===window)//truefunctionfn(){console.log(this===window)}fn()//true(function(){console.log(this===window)//true})()setTimeout(function(){console.log(this===window);//true},500)2:如果函数在对象函数中作为对象的属性被调用,则this指向对象。varx=10//相当于window.x=10varobj={x:20,f:function(){console.log(this.x)},s:function(){console.log(this.x))//20functionfn(){console.log(this.x)}returnfn//虽然函数f定义在obj.fn内部,但它仍然是一个普通函数,this仍然指向window}}varfn=obj.ffn()//10obj.f()//20ob??j.s()()//10先调用fn()为什么结果是10,因为新建了一个变量fn,等价到fn=function(){console.log(this.x)},函数中的this默认为window,所以输出为10。在obj.f()中,this指向obj,所以this.x=obj。x,输出结果为20。3:构造函数中构造函数创建的实例的属性指向构造函数的原型。functionMan(name){this.name=name}Man.prototype.getName=function(){//this指向Manreturnthis.name}consttom=newMan('tom')console.log(tom.getName())//'tom'//切记不要修改构造函数的返回值,会改变默认点,比如functionMan(name){this.name=namereturn{name:'lily'}}人.原型。getName=function(){//this指向Manreturnthis.name}consttom=newMan('tom')console.log(tom.name)//'lily'4:箭头函数的this箭头函数是在定义函数的时候绑定的,而不是在执行的时候绑定的。箭头函数中的this依赖于函数创建时的作用域环境。//第一种情况varx=10varobj={x:20,f1:function(){console.log(this.x)},f2:()=>{console.log(this.x)//分towindow}}obj.f1()//20ob??j.f2()//10//第二种情况varname="jack"varman={name:'tom',f1:function(){//这里是等于下面setTimeout函数下的thisvarthat=thissetTimeout(()=>{console.log(this.name,that===this)//'tom'true},0)},f2:function(){//这里的this不等于下面setTimeout函数下的thisvarthat=thissetTimeout(function(){console.log(this.name,that===this)//'jack'false},0)}}man.f1()//'tom'trueman.f2()//'jack'falsesetTimeout默认指向window,但是,在箭头函数中,this的作用域环境在man中,所以this指向男人。也就是说这个时候这个可以忽略包裹在它周围的setTimeout定时器函数,看看上层的作用域。5:在dom节点中,尤其是react中的jsx语法中,我们通常需要更改dom的this点,否则无法获取到指定的执行函数。所以通常需要在函数声明中使用bind来绑定事件。//html
