面试问题:如何正确理解this

266 阅读3分钟

在js中this关键字经常会用到,this的指向问题也是容易出错、很多人会混淆的概念的地方?如何快速的记住this的指向。

涉及面试题:如何正确判断 this?箭头函数的 this 是什么?

我这边准备了诀窍,看到相应场景,就可以确定了~~

在 ES5 中,其实 this 的指向

->我们一般只研究函数执行的时候里面的this

->this是谁和当前的函数在哪执行和在哪定义没有半毛钱的关系

function fn1(){alert(this);} 
//此时 this是a 弹出1,2,fn1(){alert(this);},3var a = [1,2,*fn1*,3];
​
a[2]

场景1:this 永远指向最后调用它的那个对象

通俗讲:函数执行的时候,函数名之前是否有".",有的话"."前面是谁this就是谁,没有的话this就是window

oDiv.onclick=function(){
​
   //匿名函数中的this->oDiv
​
   fn();//fn函数中的this->window
​
 };
​
 [].slice(0);//->slice中的this是[][].__proto__.slice(0);//->slice中的this是Array.prototype 

-->我们自己在数组原型中编写的方法,一般情况下我们函数中的this就是当前我们要操作的这个元素

Array.prototype.distinct=function(){
​
   //this->我们当前要操作的这个数组
​
 };[1,2,2,3,1,2,3,2,1].distinct();

场景2:自执行函数中的this永远是window

 (function(){ //this->window })();
​
 ~function(){ //this->window }();window.setTimeout(function(){
​
   //this->window
​
 },10);
​
 ary.sort(function(a,b){
​
   //第一个匿名函数(参数)在执行的时候里面的 this->window
​
 });
​
 ary.forEach(function(){
​
   //第一个匿名函数(参数)在执行的时候里面的 this->window
​
   //但是如果context传递了值(第二个参数传递值了)那么这个方法中的this就是context
​
 },context);
​
 str.replace(reg,function(){
​
   //this->window
​
 });

场景3、给元素的某一个事件绑定方法,当事件触发的时候,方法中的this是当前元素本身

 [DOM零级事件绑定]
​
 oDiv.onclick=function(){
​
   //this->oDiv
​
 };
​
 [DOM二级事件绑定]
​
 oDiv.addEventListener("click",function(){
​
   //this->oDiv
​
 },false);
​
 //在IE6~8下使用attachEvent
​
 oDiv.attachEvent("click",function(){
​
   //this->window
​
 });

场景4、在构造函数模式中,我们的this.xxx=xxx中的this是当前的类的一个实例

 function Fn(){
​
   this.x=100;//this->f x是给当前实例f增加的私有的属性
​
 }
​
 Fn.prototype.getX=function(){
​
   console.log(this.x);
​
 };
​
 var f=new Fn;
​
 f.getX();//getX中的this->f
​
 f.__proto__.getX();//getX中的this->Fn.prototype

\

场景5)call和apply强制改变this的指向->以上所有的this情况在遇到call/apply的时候都不好使,都已强制改变的为主

obj.fn.call(1);//this->1

一般情况下,我们执行call方法第一个传递的参数值是谁,那么fn中的this就是谁

  • [在非严格模式下]

第一个参数没有传递值、传递的是null、传递的是undefined fn中的this都是window

  • [严格模式下]

第一个参数传递的是谁this就是谁,传递null/undefined,fn中的this都是对应的null/undefined,不传递值默认也是undefined

例子:

var a = 20;
​
var obj = {
​
   a: 10,
​
   c: this.a + 20,
​
    fn: function () {
​
       return this.a;
​
   }
​
}
​
 
​
console.log(obj.c);  // 输出 40console.log(obj.fn());   // 输出 10

箭头函数

箭头函数的 this 始终指向函数定义时的 this,而非执行时。 ,箭头函数需要记着这句话:“箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined”。

下面让我们看看箭头函数中的 this

function a() {
  return () => {
    return () => {
      console.log(this)
    }
  }
}
console.log(a()()())

首先箭头函数其实是没有 this 的,箭头函数中的 this 只取决包裹箭头函数的第一个普通函数的 this。在这个例子中,因为包裹箭头函数的第一个普通函数是 a,所以此时的 thiswindow。另外对箭头函数使用 bind 这类函数是无效的。

感谢

到此,本篇介绍到此结束,感谢您的阅读~~