[JavaScript Note] — 淺談 JavaScript #4
Introduction & 前言
這章節主要筆記關於 This 的一些淺談,剛學 JavaScript 時就常常聽到『你真的了解 This 嗎?』、『This 到底指的是什麼?』,剛好在 JavaScript 核心篇的一個章節提到 This ,課後終於小了解關於 This 的三兩事,如果沒有搞清楚,常常會在錯誤的作用域裡做事情呢,話不多說,下面就開始來認識認識 This 吧。
接下來的每一章,不免俗的都會來一句:
本篇文章一切皆為筆記作用,有任何錯誤及問題,歡迎理性指教及討論,詳情請查閱公開課程說明書。
Summary & 摘要
本系列將會淺談 JavaScript ,希望給未來自己當作筆記以及剛接觸 JavaScript 的夥伴們,甚至能帶點不一樣觀點或您沒聽過的觀點給大家,所以不會太過深入的討論。
關於淺談的主題將會大致分為下列幾項,項目可能會做更動。
本章討論的幾個關鍵標題為下列幾項。
This 是什麼?
This 的特性
關於箭頭函式對 this 的影響
This 是什麼?
關於 JavaScript 的 This 其實上 Google 就會發現好多大神的文章,究竟為什麼 This 這麼重要呢?在相關文章中能看見,如果你搞清楚 This 你就能掌握到程式將會怎麼走,也能掌握程式在對的地方執行對的事情。
JavaScript 函式內的 this 關鍵字 表現,和其他語言相比略有差異。在嚴格模式與非嚴格模式下也有所不同。
通常,this 值由被呼叫的函式來決定。它不能在執行期間被指派,每次函式呼叫調用的值也可能不同。ES5 引入了 bind 方法去設置函式的 this 值,而不管它怎麼被呼叫。ECMAScript 2015 也導入了定義 this 詞法範圍的箭頭函式
— 擷至 MDN
This 的特性
原理或是理論的部分這邊就不過多的詳細描述,但是主要還是要說一些比較淺顯易懂的東西。關於 This 的特性有幾點:
不需宣告。
每個執行環境都有自己的 This 關鍵字。
This 和 Function 如何宣告沒有關聯性,和被呼叫方式有關。
在嚴格模式下,與在簡易模式下很不同。
在我們打開網頁 F12 之後開啟 Sources 然後就能看見最一開始的 This 指的是 Windows,而隨著我們的 Function , This 的指向位置又會開始改變。
1 | function moreThis() { |
上面提到到所謂的 **嚴格模式(‘use strice’)**,在 JavaScript 裡有一個靜默的小錯誤,不至於影響程式進行將會被忽略不會跳出警告,而使用 嚴格模式(‘use strice’) 後將會直接看見,而 嚴格模式(‘use strice’) 也可以依照部分環境加入,意思就是這個 Function 我想要加入,另一個不要其實也可以。
2020.07.31 後更:
關於箭頭函式對 this 的影響
廢話前言
沒想到過了快一年才回來補充,最近剛好在挑戰六角學院的 JS 60 Day,有興趣可以看看我的文章 [Hexschool JS60 Training] — 60天 JavaScript 學徒試煉 Day1-30 及 [Hexschool JS60 Training] — 60天 JavaScript 學徒試煉 Day31-60。
在第三十九天練習時碰到的題目剛好跟之前的 JS核心 有相關,就補充在這邊啦!
關於 ES6 的歷史,在這個系列前一章 [JavaScript Notes] — 淺談 JavaScript #3 有介紹到,這邊大致再帶過一次。
ES 又稱 ECMAScript,Script 代表著腳本,而 ECMAScript 提供了腳本語言需要遵守的規則、細節和規範, JavaScript 是實現 ECMAScript 的規範後所誕生出來的語言。簡單點來說就是一些可以讓你更簡單做事情的 Function 及 一些寫 Code 規範,更詳細的發展歷程可以點 傳送門 查看。
進入正題
這邊雖然大家可能已經知道箭頭函式是做什麼的,但還是要提一下,在剛學習 JS 一陣子後可能會開始發現很多很酷炫的寫法,比如常見的 箭頭函式、解構、字串模板…等等,以下為 箭頭函式 的範例:
1 | // 舊寫法 |
上面可以看到 箭頭函式 取代了 function
,雖然剛開始不是很習慣,但寫久了會變得很直覺,而且省下很多時間,身為工程師就必須能多懶就多懶,但是又要能懶到要處,讓人一看 Code 就知道你在寫蝦咪碗糕!
所以上面的例子我們還能這樣省:
1 | // 箭頭函式 寫法 |
夠省吧!簡單的說只要記得下列幾點:
function
改為=>
帶有參數情況下,
()
必須移到=>
箭頭前,且如果只有一個參數情況下,可省略()
,但若 沒有參數 或 一個以上的參數 情況下,一定要帶括號!單一行陳述不需要
{}
呼應主題 This
一篇好的文章結尾處是必須要呼應主題的,既然這篇文章是在講 This,那這邊就要再回來題 箭頭函式 對 This 的影響。
首先我們先記得兩點關於 This 的差別:
傳統函式 => 依呼叫的方法而定
箭頭函式 => 綁定到其定義時所在的物件
1 | var name = '王小明'; |
上述例子很清楚可以看見使用 箭頭函式 的 This 會穿過原本的區塊直接指向外層的 window,這是因為 箭頭函式 的 This 會綁定在 其定義時所在的物件
,一般建立函式都是在 window 下,所以很自然就會指向 window,那要怎麼才能指向函式呢?
這邊再說一個比較好記的方式:
建立在物件內的函式,才會影響箭頭函式的 This:
1 | var fun = () => { |
簡單說就是如果你的 function 有被物件包起來,這時候 This 指向的位置就不會是 window,因為你並不是建立在 window 上的,而是 Object 上的。
注意:上方示範的箭頭函式,適用於原本一般的函式。
call,apply,bind
關於這三個可以參考 JavaScript - call,apply,bind,會提到這三個屬性是因為在 箭頭函式 裡, This 是被綁定的,所以 call()
無法修改 This,call()
或 apply()
呼叫箭頭函式只能傳入參數。
建構函式 Out
如果使用 new 運算子,箭頭函式 不可作為建構式使用;若使用於建構式,會在使用 new 時候拋出錯誤(範例為 MDN)。
1 | var Foo = () => {}; |
DOM 監聽
記得前面提過的 This 會綁到 window 上嗎?所以如果拿來當 監聽事件 的作用會錯誤。
1 | var name = document.getElementsById('name_input'); |
上述例子為參考 卡斯伯老師 - 鐵人賽:箭頭函式 (Arrow functions) 修改。
小結
關於 箭頭函式 或是其他一些 ES語法糖 雖然很方便,但總還是會有需要注意的地方,但我們並無法都預先知道所有的錯誤, 就算知道了也可能很快就會忘記,所以最好的作法就是多練習,多犯錯!
Conclusion & 結論
本篇其實在原本就是打算做筆記之用途,因為實在有太多的大神已經寫了好多篇關於 This 的文章,沒有十足把握的話其實覺得多寫一篇關於 This 的文章真的是很沒意義,不過既然是自己要作為筆記用途,那就多少寫一些多少記一些囉。
更多關於 This 就等之後補上囉~
參考網站
- 六角學院 — JavaScript 核心篇
- MDN — This
- TechBridge 技術共筆部落格 — 淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂
- Kuro’s Blog — What’s THIS in JavaScript ? [上]