在写js、react等代码的时候,经常会遇到使用this的情况。当我满怀信心写完代码点击运行时,发现报错this.xxxisundefined或者this.xxxisnotafunction,butxxxisclearlydefinedinyourcodeinyourcode。为什么会出现这些错误?其实就是this指向的对象中没有定义xxx。所以了解这个方向是非常有必要的。1.执行上下文在开始讲这个之前,先简单说一下执行上下文。执行上下文分为三部分:变量对象(VariableObject,VO)作用域链this,这里的this就是本文要讲的this。执行上下文分为:全局执行上下文函数执行上下文全局执行上下文在代码执行时创建,函数执行上下文在函数调用时创建。同一个函数,在不同的时间调用,会创建不同的执行上下文。2.this的指向由于this存在于执行上下文中,而执行上下文是在代码执行和函数调用时创建的,因此this的指向也是在代码执行和函数调用时确定的。this可以在不同的场景下使用,this的指向分为三种情况:this在全局this函数中,this在构造函数中,this在全局this在浏览器中,this在全局指向window中,节点。js中的globalthis指向地球。变量a=1;控制台日志(这个);//windowconsole.log(this.a);//1console.log(window.a);//1console.log(this===window);//true函数中的this按函数调用方式分为以下两种情况:this当函数作为对象中的方法调用时,this1在声明函数中,this在对象方法中当函数被独立调用当函数作为对象中的方法被调用时,函数中的this指向函数的所有者。变量a=111;varobj={a:222,func:function(){console.log(this);//objconsole.log(this.a);//222}}对象函数();at这里调用了func函数作为obj对象中的一个方法,所以func中的this指向了func函数的拥有者,也就是这里的obj2。独立调用函数时,函数中的this指向全局上下文中的this为window;在严格模式下,这是未定义的。vara=111;函数func1(){vara=222;控制台日志(这个);//窗口console.log(this.a);//111}func1();functionfunc2(){“使用严格”console.log(this);//未定义}func2();ES6箭头函数中的this箭头函数中的this点是在函数定义时确定的,这与声明式函数定义不同。定义箭头函数时,this指向的函数,thisvarfunc=()=>{console.log(this);//窗口}函数();func函数是一个箭头函数,所以func函数里面的this在定义的时候就确定了,定义它的执行上下文就是全局执行上下文。上下文中的this指向window,所以func函数的this也指向this。变量a=111;varobj={a:222,func:function(){varfun2=()=>{vara=333;控制台日志(this.a);}fun2();}}对象。功能();这段代码中,调用func函数时,func中的this指向obj,而func函数中又定义了一个箭头函数,所以func2函数中的this指向了func函数this的执行上下文,所以最后的打印输出是obj对象中的a(222)。构造函数new中this构造函数创建对象的过程:创建一个新对象;将构造函数的this指向这个新对象;执行构造函数的内部代码;在构造函数中返回这个新对象指向生成的对象functionObj(a){this.a=a;this.func=function(){console.log(this);控制台日志(this.a);}}varobj=newObj(2);obj.func();这段代码中,使用new实例化对象后,调用对象中的func函数,其中func函数是obj对象中的一个方法,所以func函数中的this指向函数的所有者,所以这里打印了结果是2。3、改变this指向的方法可以在函数vara=111;中使用call,apply,bind改变this指向。varobj1={a:222,func:function(){console.log(this);//{a:333}console.log(this.a);//333}}varobj2={a:333,}obj1.func.call(obj2,);这里在调用obj1中的func方法时,会在后面添加call后,将func中的this改为指向call中指定的obj2,所以最后打印出来的是333,这里调用call,函数将立即执行。apply方法的作用与call相同。它们的区别在于调用是一个一个传递其他参数,而apply传递的是一个数组,这样当传递的数据数量增加时,就不需要Like调用了,在一个一个调用后写在括号里.例如:obj.func.call(obj2,param1,pram2,param3)obj.func.aply(obj2,[param1,pram2,param3])bind也可以改变函数中的this点,它和call的区别而apply是,它返回一个新函数,并不像call和apply那样立即执行。4.其他情况下的this点当函数作为DOM事件处理器使用时当函数作为事件处理器使用时,它的this指向触发事件的元素。函数func(){console.log(this);//元素}varbutton=document.getElementsByTagName('button');button.addEventListener('click',func);当使用addEventListener向DOM元素添加事件时,函数this将指向DOM元素。当用作内联事件处理程序时
