# Can you offer a use case for the new arrow => function syntax? How does this new syntax differ from other functions? ## :bulb:解答: One obvious benefit of arrow functions is to simplify the syntax needed to create functions, without a need for the function keyword. The this within arrow functions is also bound to the enclosing scope which is different compared to regular functions where the this is determined by the object calling it. Lexically-scoped this is useful when invoking callbacks especially in React components. :::info * 箭頭函式簡化語法,不需寫function關鍵字 * 箭頭函式中的this綁定在封閉範籌(enclosing scope)中,和常規函式中的this指向呼叫的物件不同,this變數強制綁定 * 在React組件中呼叫回呼函式(callbacks)時,語彙範籌(Lexically-scoped)相當有用。 ::: <hr/> ## 一、箭頭函式的語法和範例: ### 箭頭函式背景: 為了能夠以更簡短的方式建立函式,Javascript ES6新增的新語法。 由於中間的 => 形似箭頭而得名。 雖然口頭上都稱呼為箭頭函式(Arrow Function),但實際上他是箭頭函式運算式(Arrow Function Expression)。 <br> ### 箭頭函式的使用規則: 箭頭函式的語法:接受一個參數 (param) 並回傳一個表達式 (expression) 的值 ``` param => expression ``` * 一般函式 function 由 => 符號代替 * 參數在只有一個的時候,括弧可以省略 * 表達式若只有一個,那麼該表達式的值即為回傳值,且可省略 {} * 程式區塊則和一般函式無異 * 箭頭函式無法用於建構式(constructor),使用new會產生錯誤。 * 箭頭函式可以取代原有使用var self = this或.bind(this)的情況,它可以在詞彙上綁定this變數。 ```javascript= var person = { name: 'becky', gender: 'female', testing: function() { (() => { console.log(this) })() } } person.testing() ``` ### 語法範例: 正常寫法 ```javascript= const sayHi = (someone) => { return someone + 'Hi' } console.log(sayHi('Becky')) ``` 縮寫,單一行陳述不需要 {} ```javascript= const sayHi = (someone) => someone + 'Hi' console.log(sayHi('Becky')) ``` 只有一個參數可以不加括號 ```javascript= const sayHi = someone => someone + 'Hi' console.log(sayHi('Becky')) ``` 沒有參數時,一定要有括號 ```javascript= const sayHi = () => 'Becky' + 'Hi' console.log(sayHi()) ``` <br> ## 二、箭頭函式和常規函式的差異: | | 箭頭函式 | 常規函式 | | | -------- | ------------------------------------------------------------------------------------- | ---------------------------------- | --- | | 語法組成 | 無須function關鍵字、簡化圓括弧()、花括弧{} | function關鍵字、params引數、花括號 | | | 語法使用 | 只能用賦值式寫法 | 賦值式、宣告式寫法 | | this | 不會建立自己的this,它只會從自己的作用域鏈的上一層繼承this,所以預設等於上一層this的值 | 依據呼叫函式的物件決定 | | 不可使用的情況 | 物件中的方法、Prototype 中使用 this、DOM 事件監聽、建構式 | | | | 綁定方法 | 無法使用call方法 | 可使用call方法指定綁定物件 | | <hr/> ## 三、語彙範疇(Lexically-scoped): Arrow Functions 則不會有自己的 this 引用物件,呼叫 this 時,會沿用語彙環境外圍的 this。 ``` var whatsThis = () => { return this; } console.log( whatsThis() ); // window ``` 看的是語彙位置,往外一層是 Global Context,不管在一般模式或嚴謹模式,this 都是 Global 物件: [Arrow Functions 的 this 判斷原則](https://hackmd.io/fhojRyNKQAWyZ_ZmJhL5Gg) # ### 範疇(Scope) 編譯器或 JavaScript 引擎藉由識別字名稱(identifier name)查找變數的一組規則。 #### 編譯器怎麼理解程式碼? **1.由上而下編譯後執行:** 程式執行前將程式碼由上到下逐行轉為電腦可懂的命令,再執行編譯後的結果。 **2. JavaScript 引擎的毫秒時間差:** 即時編譯程式碼(執行前)->執行編譯後指令,此過程為毫秒 (ms) 時間差。 **3. 編譯三步驟:**  抽象語法樹(abstract syntax tree,AST)  **4.編譯的過程中,JavaScript 引擎、編譯器和範疇會互相溝通以完成工作。它們各自負責的任務有:**  5.**範例:** ``` var a = 2; ```  [編譯流程圖](https://gitmind.com/app/doc/fd63209006) # ### 語彙範疇的運作方式: #### 語彙範疇(lexical scope) * **定義:** 語彙分析時期所定義的範疇,而範疇的劃分在程式碼撰寫時就已決定。 * **試著區分有幾個範疇?** ``` function foo(a) { var b = a * 2; function bar(c) { console.log(a, b, c); } bar(b * 3); } foo( 2 ); // 2 4 12 ```  (1) 最外面的範疇即全域範疇,識別字有 foo。 (2) 中間的範疇是在 foo 裡面,識別字有 a、b、bar。 (3) 最裡面的範疇是在 bar 裡面,識別字只有 c。 * **查找識別字:** 範疇的劃分說明了 JavaScript 引擎如何尋找識別字的所在之處 1. **遮蔽(shadowing):** A.相同的識別字同時出現在不同的巢狀範疇 B.巢狀範疇內層找到第一個符合的識別字就會停止搜尋 2. **全域變數(global variable):** A.全域變數會自動變成全域物件的屬性 B.使用 window.a 來避免 a 被巢狀範疇內層的同名變數遮蔽 ## 四、參考資料: [語彙範疇](https://cythilya.github.io/2018/10/18/lexical-scope/) [JavaScript - Lexical Scope](https://ithelp.ithome.com.tw/articles/10194745) [箭頭函式 this](https://www.gushiciku.cn/pl/ggOV/zh-tw) [What advantage is there for using the arrow syntax for a method in a constructor? by phoebe](https://hackmd.io/fhojRyNKQAWyZ_ZmJhL5Gg) [版本二 Javascript this by Sol](https://hackmd.io/SpT1T6nuTw2QTWp0az4kJw) https://ithelp.ithome.com.tw/articles/10221214 https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/arrow_function.html https://cythilya.github.io/2018/10/17/what-is-scope/
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up