当前位置: 首页 > Web前端 > JavaScript

原型、原型链和闭包,而this指向问题

时间:2023-03-26 22:42:13 JavaScript

闭包中查找自由变量是在定义函数的地方,是向上作用域查找,不是在函数所在的地方被执行。this的调用场景:1.作为普通函数调用。2.使用callapplybind被调用。3.作为对象方法调用。4.在类方法中调用。5.作为箭头函数调用。当函数被调用时,它所取的值是确定的。箭头函数中的this总是指向函数定义处的this值。细分后可以分为四种:1.箭头函数绑定2.关键字new绑定3.显式绑定4.隐式绑定5.默认绑定以上绑定优先级从高到低,同时JS引擎只会将此时存在的具有最高优先级的绑定绑定到此。另外,settimeout、setInterval等函数的回调函数的this指向window,因为这两个方法是在全局环境下执行的,所以执行window。下面是一个如何绑定的简单示例:functionfoo(){console.log(this.bar);}varbar="bar1";varo2={bar:"bar2",foo:foo};varo3={bar:"bar3",foo:foo};富();//"bar1"-默认绑定o2.foo();//"bar2"-隐式绑定o3.call({bar:"bar4"});//"bar4"被显式绑定,使用{bar:"bar4"}作为"this"functionfoo(){this.test="test";console.log(this.bar+""+this.test+""+test);}varbar="bar";vartest=newfoo();//"undefinedtestundefined"关键字new绑定,默认返回函数foo的this。函数Person(){this.age=0;setTimeout(function(){console.log(this.age);//输出未定义},1000);}varp=newPerson();functionPerson(){this.age=10;setTimeout(()=>{console.log(this.age);//输出10},1000);}varp=newPerson();//上面是箭头函数的效果,window的this本来应该执行的,定义的时候强制指向了Person函数内部,并且输出了10个。如果将new关键字放在函数调用前,JS编译器会做四件事:1.创建一个新的空对象2.将这个对象链接到原型对象3.这个对象绑定为this4。如果这个函数不返回任何东西,它会默认返回这个。另一个看似被new关键字绑定的例子实际上是隐式绑定的:functionPerson(){this.name="Smiley";this.sayName=function(){console.log(this);console.log(this.name);};}letperson=newPerson();letsayNameCopy=person.sayName;sayNameCopy();//结果是windowundefined//person.sayName此时相当于function(){//console.log(this);//console.log(this.name);//};//然后让sayNameCopy=person.说名字;相当于在全局窗口上定义sayNameCopy。由于窗口中没有name,this和this.name输出窗口并undefined。再举一个看似绑定但实际上是箭头函数绑定的例子:functionPerson(){this.name="Smiley";this.sayName=()=>{console.log(this);console.log(this.name);};}letperson=newPerson();person.sayName.call({name:"Nicolas"});//结果是{name:'Smiley',sayName:?}"Smiley"//由于Person函数中的this.name是一个箭头函数,所以this指向了内部定义sayName的Person函数。