如何快速的判断this指向

this指向问题

是不是经常搞不懂所谓的this指向,到底指向谁?一头雾水,越看越头大

别急 ! this指向是在面试中经常会考到知识点,也就要求我们必须掌握,但是大多数人总是会判断错误,接下来就仔细看一下这篇文章吧

this指向可以分为四种情况

我们从最容易分辨的开始

1. obj.fn() 也就是方法调用模式   this----> obj

这个其实也是比较好理解的,就是谁调用指向说,this就指向我们的obj

注意: 区分obj.fn() 和 obj.fn ,一个是调用了函数,是函数执行之后的 ,一个是赋值,把函数obj了,并没哟调用

          两者在this指向上也有区别,obj.fn()  this指向obj,而后者指向window

是不是觉得自己好像懂了一点点了,是不是觉得这个obj.fn()太简单了,别急,我们做几道题来巩固一下

 // 练习1
    function sayHi() {
      console.log('Hello,', this.name);
    }
    var person = {
      name: 'YvetteLau',
      sayHi: sayHi
    }
    var name = 'Wiliam';
    // 这个其实也很好理解,就是典型的obj.fn() 所以this--->person
    person.sayHi();  // YvetteLau

是不是自信心来了,来看下一题

//练习2
function sayHi() {
      console.log('Hello,', this.name);
    }
    var person2 = {
      name: 'Christina',
      sayHi: sayHi
    }
    var person1 = {
      name: 'YvetteLau',
      friend: person2
    }
    // 当我们的obj.fn()多层调用的时候,我们不管调用了多少层,this都是指向离他最近的obj的,也就是this---> friend
    person1.friend.sayHi();  // Christina

有新增加了一个小的知识点,当this多层调用的时候,我们的this指向就只会指向自己最近的,无论多少层,还是指向最近的obj

再来看一个让你怀疑人生的题

// 练习3    
    function sayHi() {
      console.log('Hello,', this.name);
    }
    var person1 = {
      name: 'YvetteLau',
      sayHi: function () {
        setTimeout(function () {
          console.log('Hello,', this.name);
        })
      }
    }
    var person2 = {
      name: 'Christina',
      sayHi: sayHi
    }
    var name = 'Wiliam';
    person1.sayHi();   // Wiliam
    // 这个就是需要区分setTimeout和sayHi里面的有没有关系?
    // 答案肯定是否定的,没有一点关系,就像你家的钱和隔壁家的,完全没有关系,有关系也就是都是钱而已
    // 此时 person2.sayHi并没有加括号,也就是赋值,此时this---> window
    setTimeout(person2.sayHi, 100);  //Wiliam
    setTimeout(function () {
      //这个就是真的典型的obj.fn() ,所以this--> person2
      person2.sayHi();  //YvetteLau
    }, 200);

有的人看见obj.fn就毫不犹豫的相信this-->obj,所以就认为person1.sayHi() 中的this指向person1,就直接接的输出为YvetteLau

但是我们需要考虑一下,person1.sayHi()里面有个函数,也就意味着,虽然sayHi里面的this指向this,单数setTimeout里面的this并不指向person1 ,而是指向window,所以打印出来wiliam\

好了,可别怀疑自己,接下来就是真的容易的啦

2. 上下文调用模式 this  --->  call apply bind的第一个参数

我们用的方法中,call apply bind的第一个参数就是用来改变我的this指向的,this就指向第一个参数

但是,需要注意,当把unll 和undefined当做第一个参数传递给它们的时候,this指向就是不生效了,this-->window

这个也可以简单理解为,你都把unll和undefined传给call了,this能指向谁?指向null?也不现实,所以它只能去外面找window

   function sayHi() {
      console.log('Hello,', this.name);
    }
    var person = {
      name: 'YvetteLau',
      sayHi: sayHi
    }
    var name = 'Wiliam';
    var Hi = person.sayHi;
    // this --> person
    Hi.call(person);  // YvetteLau

3. new  this---->新创建的对象

看到这个,我们首先需要明确new做了四件事情

1. 创建一个新的对象

2. 将构造函数赋值给新的对象,并将this指向新的对象

3. 执行构造函数

4. 返回这个对象

这个也就不难理解,this就指向我们新创建的对象

    function sayHi(name) {
      this.name = name;
    }
    var name = 'zs'
    var Hi = new sayHi('Yevtte');
    console.log('Hello,', Hi.name); // Yevtte

4. 其他    this ---> window

首先回顾一下下上面三种情况  

 1.obj.fn() this-->obj   2. call apply bind this-->他们的第一个参数  3. new  this-->新创建的对象

有了这三个明显的特点,其他的就是咱们的第四种    this   --->  window

不绝对,但是大部分都是

function sayHi(name) {
      console.log('Hello,', this.name);
    }
    var name = 'YvetteLau';
    sayHi('zs'); // YvetteLau

这个可能也会有疑惑,但是仔细判断一下, sayHI('zs') ,不符合obj.fn()也没有call和new,所以就是第三种情况,this-->window

有没有觉得自己有一点稍微懂了一点点了,再给一个终极大烧脑的题

var number = 5; // 10   20 
    var obj = {
      number: 3,   //6  
      fn: (function () {
        var number;  //    3   9   27    
        this.number *= 2;  // 10
        number = number * 2;  // NaN
        number = 3;  //3  
        return function () {
          var num = this.number;  //10   3 
          this.number *= 2;  // 20  6 
          console.log(num);  
          number *= 3;    // 9    27 
          console.log(number);   
        }
      })()
    }
    var myFun = obj.fn; // this--> window
    myFun.call(null); //this-->window     10   9 
    obj.fn();   //this --> obj    3    27 
    console.log(window.number);  // 20

最后打印出来就是  10  9   3  27 20 

不要怀疑自己,因为里面还运用到了一个匿名函数自调用

当var了obj的时候,就已经执行了fn里面的函数,并且返回了return后面的值,

此时obj.fn就已经等于了return后面的这个函数

所以在下面执行的时候,就不会再执行return前面的,直接从return后面的开始,然后判断每个引用的this指向就可以得出值了

好好思考,不懂也可以交流

发布了64 篇原创文章 · 获赞 19 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44114310/article/details/89005275
今日推荐