筆記:淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂


Posted by rockyooooooo on 2021-07-05

淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂

從綁定角度來看:

What’s THIS in JavaScript ?

  • 預設綁定(Default Binding):
    宣告在 Global Scope 的變數,就是全域物件(window 或 global)的屬性,所以當 function 被直接呼叫,或是用 func.call(null), func.apply(undefine),此時的 this 會自動指向到全域物件。在 use strict,指向到全物物件的 this 則會是 undefine
  • 隱含式綁定(Implicit Binding):
    呼叫 function 的時機點
  • 顯式綁定(Explicit Binding):
    call(), apply(), bind() 來直接指定 this
  • new 關鍵字綁定:
    當用 new 來建立一個先的物件,這個新的物件會被設為 this 綁定的目標

顯示綁定優於隱含式綁定

從規範角度來看:

太難了,看文章:JavaScript深入之从ECMAScript规范解读this

想成用 call() 來呼叫 function:

淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂

呼叫 function 的方法改成用 call() 的形式來看,可以解決九成的 this 問題

例如:obj.hello() 就看成 obj.hello.call(obj),這時 this 就是 obj,如果是 hello(),因為前面沒有東西,就看成 hello.call(),也就是 window.hello.call(window)window 是全域物件,在 node.js 則是 global

技術總結

  • 物件導向下的 this 就是 instance 本身
  • JavaScript 的 this 難懂的原因在於,JavaScript 在任何地方都可以存取到 this
  • 脫離了物件,this 的值就沒有什麼意義
  • 沒意義的情況下,this 的預設綁定:
    1. 嚴格模式下是 undefined
    2. 非嚴格模式下,在瀏覽器是 window
    3. 非嚴格模式下,在node.js 是 global
  • 可以用 call()apply() 來規定 this 的值
  • 也可以用 bind() 來綁定 this 的值,一旦綁定了就不會再改變了
  • call(), apply(), bind() 在非嚴格模式下,傳進去的值如果是 primitive type,會強制轉換成 object
  • this 的值跟作用域或程式碼的位置都無關,只跟「如何呼叫」有關
  • 小撇步:把 function call 轉成用 call(),例如
const obj = {
  num: 1,
  log: function() {
    console.log(this.num)
  }
}

obj.log() // 1
obj.log.call(obj) // 轉成 call 來看,就很簡單
  • 箭頭函式的 this,就是「宣告這個箭頭函式的地方的 this 是什麼」
  • 箭頭函式沒有自己的 this,所以用 call()apply() 只能傳參數,thisArg 會被忽略
  • 優先順序:new 綁定 > 顯示綁定 > 隱含式綁定 > 預設綁定

參考資料

淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂
What’s THIS in JavaScript ?
鐵人賽:箭頭函式 (Arrow functions)
JavaScript深入之从ECMAScript规范解读this
箭頭函式
this 的值到底是什么?一次说清楚
JS this

tags: 筆記

#note #javascript #this







Related Posts

Android 時間格式轉換筆記

Android 時間格式轉換筆記

Get讀取與Post傳送比較與傳送原理

Get讀取與Post傳送比較與傳送原理

[CSS] 切版眉角的部份

[CSS] 切版眉角的部份


Comments