前端讀者 | 嗨,你知道this嗎

本文來自 @position_柚子,地址:https://juejin.im/post/5995c7a76fb9a0247a60c407javascript

在平時的代碼中,相信你們常常用到 this,但是你真的明白此 this 真的是你認爲的 this 嗎?今天柚子君總結了一下平時用到的 this 的場景,你們走過路過不要錯過啊~java

首先我們先來看一下《JavaScript 高級程序設計》上是怎麼說的。windows

this 對象是在運行時基於函數的執行環境綁定的:在全局函數中,this 等於 windows,而當函數被做爲某個對象的方法調用時,this 等於那個對象。瀏覽器

還有一種狀況,在《深刻理解 ES6》一書中寫道:app

若是箭頭函數被非箭頭函數包含,則 this 綁定的是最近一層非箭頭函數的 this,且不能經過 call()、apply() 或 bind() 方法來改變 this 的值。函數

首先看一下非箭頭函數的狀況:post

1、普通函數調用

這是一個普通的函數聲明,在這種狀況下,this 是指向 window 的:this

var test = '哈哈哈';
function thisHandler() {
    console.log('test:',this.test,'this:',this);
}
thisHandler() // test: 哈哈哈 this: window

其實上面的代碼就至關於 window 調用 thisHandler(),因此這時 this 指向 windowprototype

var b = '哈哈哈';
function thisHandler() {
    console.log('b:',this.b,'this:',this);
}
window.thisHandler() // b: 哈哈哈 this: window

2、做爲對象的方法調用

看成爲對象的方法被調用時,this 這時就指向調用它的對象。設計

var thisHandler = {
  name: "柚子",
  test: function(){
    console.log('my name:',this.name); 
  }
}
thisHandler.test() // my name: 柚子

再來一個栗子:

var thisHandler = {
  name: "柚子",
  fn: {
    name: '芒果',
    test: function() {
       console.log('my name:',this.name); 
    }
  }
}
thisHandler.fn.test() // my name: 芒果

這時 this 指向的是對象 fn 了,因此,關於對象調用這一點明白了嗎,若是明白了,那不要緊,接着看下一個強化題:

var name = '柚子'
var thisHandler = {
  name: "芒果",
  fn: {
    name: '糖果',
    test: function(){
      console.log('my name:',this.name); 
    }
  }
}
var testHandler = thisHandler.fn.test
testHandler()

這裏是一秒鐘分割線

噠噠噠,答對了,這裏的 this 指向的 window,那麼這是爲何呢,哪位小盆友來回答一下。舉手:

上面說到了,this 指向的是最後調用它的對象,第一步是賦值給了 testHandler,最後執行的那一句至關於 window.testHandler()。因此這裏的 this 指向的是 window。最後輸出的就是 my name: 柚子

噠噠噠,真聰明,來闖下一關~

3、構造函數的調用

var name = '柚子'
function Bar() {
  this.name = '芒果'
}

var handlerA = new Bar();
console.log(handlerA.name);  // 芒果
console.log(name) // 柚子

其實要明白爲何會是這樣一個結果,我們就要來聊聊 new 作了哪些事情。

  • 建立類的實例。這步是把一個空的對象的 __proto__ 屬性設置爲 Bar.prototype
  • 初始化實例。函數 Bar 被傳入參數並調用,關鍵字 this 被設定爲該實例。
  • 返回實例。

弄明白了 new 的工做內容,天然而然的也明白了上面輸出的緣由。

Bar() 中的 this 指向對象 handlerA,並非全局對象。

4、apply / call 調用

使用 apply 方法能夠改變 this 的指向。若是這個函數處於非嚴格模式下,則指定爲 nullundefined 時會自動指向全局對象(瀏覽器中就是window對象)。

var name = '芒果';
var thisHandler = {
  name: "柚子",
  test: function(){
    console.log('my name:',this.name); 
  }
};

thisHandler.test(); //  my name: 柚子
thisHandler.test.apply(); // my name: 芒果

4、箭頭函數

在《深刻理解 ES6》一書中能夠知道箭頭函數和普通函數的一個不一樣之處就在於 this 的綁定。

箭頭函數中沒有 this 綁定,必須經過查找做用域鏈來決定其值。若是箭頭函數被非箭頭函數包含,則 this 綁定的是最近一層非箭頭函數的 this;不然,this 的值會被設置爲 undefined

var name = '柚子'
var thisHandler = {
  name: '芒果',
  test:() => {
    console.log('my name:',this.name,'this:',this); 
  }
}

thisHandler.test(); // my name: 柚子 this: Window

這時 this 不是指向 thisHandler,而是 Window

關於 this 的使用和體會仍是要在平時運用中理解,先了解其原理,那麼在使用的時候就如魚得水啦。

相關文章
相關標籤/搜索