總結JavaScript中this指向的問題

一、什麼是this、this又指向誰?
1.1 什麼是this

定義:this是包含它的函數作爲方法被調用時所屬的對象。這句話聽起來有點繞嘴,但一個多餘的字也沒有,定義非常準確,我們可以分3部分來理解它!
1、包含它的函數。
2、作爲方法被調用時。
3、所屬的對象

1.2 this指向誰

誰最終調用函數,this就指向誰。

二、this指向特點

1、this指向的只可能是對象。
2、this指向誰,不取決於this寫在哪兒,而取決於函數在哪兒調用。
3、this指向的對象,稱之爲函數的上下文(函數的調用者)。

1、直接調用

直接調用函數,this指向window。

	function fn() {
      var a = 1;
      console.log(this); // window
      console.log(this.a); // 2
    }
    var a = 2;
    fn();
2. 對象的形式調用

在對象上調用函數,this指向調用的那個對象。

	function xx() {
      var a = 1;
      console.log( this); // obj ====> ({a: 3, xx: ƒ})
      console.log(this.a); // 3
    }
    var a = 2;
    var obj = {
      a: 3,
      xx: xx,
    };
    obj.xx();
3. 構造函數(new操作符)

在構造函數中 this 永遠綁定在fn上,也就是說他指向new出來的那個對象,this不會發生改變。

	function Fn() {
      var a = 1;
      console.log(this); // Fn {}
      console.log(this.a); // undefined
    }
    var a = 2;
    var fn = new Fn();
4. 定時器(匿名函數)調用

定時器函數作爲window內置函數的回調函數調用,其調用的是window.setTimeout,此時的this指向window

	var a = 1;
    setTimeout(function () {
      var a = 2;
      console.log(this); // window
      console.log(this.a); // 1
    }, 1000);
5. 在箭頭函數中調用

學過ES6都知道箭頭函數本身其實是沒有thisarguments的,實際上箭頭函數中的this取決於包裹着箭頭函數的第一層普通函數的this,大白話就是離他最近的父級函數,來看一個例子:

	function ft() {
      var a = 1;
      return () => {
        console.log(this); // window
        console.log(this.a); // 2
      };
    }
    var a = 2;
    ft()();

由上面的例子不難看出,包裹着箭頭函數的第一個普通函數是ft函數,由於ft函數指向window,即在箭頭函數中調用this指向window

6. call、apply、bind

callapplybind這些改變上下文的函數其this指向取決於第一個參數。如果第一個參數爲''nullundefined等,則this指向window;如果傳遞的有參數則this指向第一個參數。
首先看不傳參數時的情況:

	function ff() {
      var a = 1;
      console.log(this);
      console.log(this.a);
    }
    var obj = {
      a: 3,
    };
    var a = 2;
    ff.call(); // window  2
    ff.apply(); // window  2
    var ff1 = ff.bind() // window  2
    ff1()

然後給他們傳遞參數時的情況:

function ff() {
      var a = 1;
      console.log(this);
      console.log(this.a);
    }
    var obj = {
      a: 3,
    };
    var a = 2;
    ff.call(obj); // obj ====> { a: 3 } // 3
    ff.apply(obj); // obj ====> { a: 3 } // 3
    var ff2 = ff.bind(obj); // obj ====> { a: 3 } // 3
    ff2();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章