--- tags: JavaScript, hexo部落格 title: 箭頭函式與 this(上) --- ## 箭頭函式 (Arrow functions) 與一般函式相比,寫法更加簡潔,也避免了某些問題。 ```javascript // 一般函式寫法 function fn(){ console.log('此為具名函式 - 函式陳述式寫法。') } var a = function(){ console.log('此為匿名函式 - 函式表達式寫法。') } // 箭頭函式 const b = () => { console.log('此為箭頭函式寫法。') } // 若函式只有單一變數,參數括號可以簡化 const c = str => { str = '簡化參數括號' console.log(str) } // 若函式內只有單一陳述行,大括號可以簡化,但沒有參數時,括號必須存在 const d = () => console.log('此為箭頭函式簡易寫法。') ``` ### 箭頭函式與一般函式的差異 箭頭函式除了寫法簡潔之外,它跟一般函式有甚麼差異? 每當搜尋相關介紹時,總會說明它沒有這些 : - `this` - `arguments` - `call()` - `apply()` - `bind()` 而這些到底是甚麼? 為什麼那三個內建函式又是甚麼? 為什麼它們看起來很陌生? 在下集會來介紹,在上集中會先介紹 `this`。 先簡易說明一下,`call()`、`apply()`、`bind()` 這三種 JS內建函式,可以影響 `this` 的運作,若使用箭頭函式的話,由於 ES6的規則,連帶的那三個函式也跟著無法使用。 而 `arguments`,它為一般函式的內建參數,在箭頭函式中無此內建參數可運用,但是可以改用 ES6的其餘參數來達到同樣效果。 ## this 看到箭頭函式的介紹時,常會看到一句話,箭頭函式沒有自己的`this`,而 this從何而來,又指向誰,為什麼會用到它? ### this是甚麼 ? - this 是 JavaScript的內建關鍵字之一 - 通常會用在函式或物件中,來呼叫自身的擁有的屬性或值等等... ### this從何而來 ? 先來看個範例 : ```javascript var a = 1 console.log(a) // 1 console.log(window.a) // 1 console.log(this.a) // 1 ``` 當我們將瀏覽器打開時,就已經建立好全域環境與執行環境,而程式碼就是寫在執行環境中,而 `this` 與全域環境一起被建立。 - 全域環境 - `this` - 執行環境 當我們要呼叫 a這個變數時,由上述範例可以知道,有三種呼叫變數 a的方式 : - 直接呼叫 - 透過全域物件呼叫 - 透過 JS 內建關鍵字 `this` 呼叫 變數 a 是由 var 宣告的,而它的執行環境在全域環境中,於是變數 a 就被建立在全域環境,接著就能透過全域物件 window 找到它。 ### this指向誰 ? 通常我們寫程式碼時,習慣在全域環境下作業,而 `this` 在呼叫自身時,**必須留意在哪個環境被呼叫,而不看在哪裡被使用**,像是以下這些例子 : * 簡易呼叫函式 ```javascript= // 在全域的環境下執行函式,`this`會呼叫全域下的變數 var name = '全域阿婆' function nameFn(){ var name = '漂亮阿姨' console.log(this.name); } nameFn() // '全域阿婆' ``` * 物件中呼叫函式 ```javascript= // 在全域的環境下執行物件中的函式,`this`則指向物件本身 const obj ={ name:'小杰', callFn(){ // 物件內函式縮寫 console.log(this.name); } } obj.callFn(); // '小杰' ``` * 物件裡呼叫函式並執行函式中的函式 ```javascript= var name = '全域阿婆'; const obj = { name:'小杰', callFn(){ // 物件內函式縮寫 function callFn2(){ console.log(this.name); }; callFn2(); } } obj.callFn(); // 相當於直接執行 callFn2() -> '全域阿婆' ``` ### 為什麼會用 this ? 在 `this` 一開始有提到,它可以用在函式或物件中,來呼叫自身的擁有的屬性或值,來看以下例子 : ```javascript= let personA = { age: 18, sayHello: function (number){ console.log(`我今年${number}歲`) } } personA.sayHello(personA.age) let personB = { age: 10, sayHello: function (){ console.log(`我今年${this.age}歲`) } } personB.sayHello() ``` 使用 `this` 可以讓程式碼簡化不少。 ## 箭頭函式與 this 上述範例中,物件裡呼叫函式並執行函式中的函式,`this` 會指向全域,而我們可以使用箭頭函式來解決這樣的問題,因為 : - 箭頭函式沒有自己的 `this` - 當箭頭函式中使用 `this` 時,它會往上一層尋找 - 也就是說,**在哪邊被使用,它就會往上一層尋找,而不看環境** ```javascript= let name = '全域阿婆' const obj = { name:'小杰', callFn () { // 物件內函式縮寫 const callFn2 = () => { console.log(this.name); } callFn2(); } } obj.callFn(); // '小杰' ``` ## 回想 - 箭頭函式怎麼寫 ? - 如何知道箭頭函式沒有自己的 `this` ? - 甚麼時候會用到 `this` ? - `this` 在不同地方會指向誰 ? - 在全域環境下,若創造一個箭頭函式並使用了 `this` ,它會指向誰 ? - 在物件中新增了一個函式並使用了 `this` ,最後在全域環境下呼叫物件內的函式,它會指向誰 ? ## 參考來源 > 1. [Schaos - 前端三十|10. [JS] 一般函式與箭頭函式的差異?](https://medium.com/schaoss-blog/%E5%89%8D%E7%AB%AF%E4%B8%89%E5%8D%81-10-js-%E4%B8%80%E8%88%AC%E5%87%BD%E5%BC%8F%E8%88%87%E7%AE%AD%E9%A0%AD%E5%87%BD%E5%BC%8F%E7%9A%84%E5%B7%AE%E7%95%B0-32ce9455ff1a) > 2. [胡立 - 淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂](https://blog.techbridge.cc/2019/02/23/javascript-this/) > 3. [Mooji - JS 原力覺醒 Day07 - 陳述式 表達式](https://ithelp.ithome.com.tw/articles/10218937) > 4. [卡斯伯 - 鐵人賽:箭頭函式 (Arrow functions)](https://wcc723.github.io/javascript/2017/12/21/javascript-es6-arrow-function/) > 5. [MDN - 箭頭函式](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions/Arrow_functions) > 7. 六角學院 - JS核心篇
×
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