iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 4
0
Modern Web

為期 30 天的 react 大冒險系列 第 4

react 大冒險-快速複習 js 的語法 day 4

經過幾天的 轟炸 複習,
今天要談的是 es6的懶人神兵—箭頭函示(arrow function) 跟 常常搞不清楚究竟誰是誰的 this
(撐過去就可以開始 react 之旅了,加油啊)
image alt

arrow function

  • 因為 arrow function 沒有 function name 所以要宣告一個變數來裝
  • 如果 傳入的參數(parameter) 只有1個 可以省略掉()
// 原本的函式長這樣
function sumFunc (a,b){
    return a+b;
}
// 改寫成箭頭函式長這樣
const sumArrow = (a,b)=> a+b;
  • 如果沒有傳入的參數(parameter) 一定要保留()
function randNum() {
    return Math.random();
}

const randNumArrow = () => Math.random();
randNumArrow(); // 執行 randNumArrow 箭頭函式
  • 如果 arrow function 執行時,只單純 return 值或只執行一件事 可以省略return{}
  • 使用箭頭函式的好處,除了省事以外,還可以協助處理掉 this 的問題,下方一併說明

this

簡單來說,this 就是 執行當下 function 的物件

This is the object that is executing the current function.

this 在不同位置,分別會代表不同的值

  • 全域(global context,簡單說就是不在任何 function 內)中,this 是 window object,且不因為是否 use strict 而改變
console.log(this === window); // true
  • 如果 this 在 function(function context) 中,要看 function 是怎麼被執行的
    1. function 被直接執行 (沒有對象 call function/normal function),且沒有 use strict ,this 為 window object
      image alt
    2. event handler 中,this 是該事件的目標DOM (EventTarget)
    function clickEvt(){
        console.log(this);
    } 
    const targetBtn =  document.getElementById('targetBtn');
    targetBtn.addEventListener('click' , clickEvt); // <button id="targetBtn">Clickkkk</button>
    
    1. 沒有對象 call function,有 use strict ,this 為 undefined
      image alt
    2. 在物件內的 function (constructor function) ,this 就是該物件
      image alt
    function Book (title){
        this.title = title;
        console.log(this);
    }
    
    const book = new Book('the road to learn React'); 
    // new 產生出新的 Book object 
    // 這裡的 this 即為 new 出來的 Book {title: "the road to learn React"} 
    

回到 使用箭頭函式的好處這回事
看看以下有點費解的例子

window.name = 'window name';

class Person {
    constructor(name) {
        this.name = name
    }
    // 在 class 上的 function
    printNameArrow() {
        setTimeout(() => {
            console.log('arrow: ' + this.name)
        }, 100)
    }
    printNameFunc() {
        setTimeout(function () {
            console.log(this); // window
            console.log('function: ' + this.name)
        }, 100)
    }
}

let personA = new Person('Mary');
personA.printNameArrow(); // arrow: Mary 
personA.printNameFunc(); // function: window name

為什麼 personA.printNameFunc(); 中的 this 會是 window object 而不是 personA?
基本上就是 setTimeout 並不是 personA 上的 method,前面提到 this 在不同作用域(function scope)內會被重新定義,而 setTimeout 是 window 上的 method,所以 this 自然就是 window object

因為 this 實在是太煩了,為了確保 this 是目標對象
所以可以使用 abc 三重奏(apply / call / bind)來綁定 this
關於 apply / call / bind 這裡簡略做個比較

bind apply call
指定this綁定的目標 指定this跟 targetFunction的參數 指定this跟 targetFunction的參數
回傳 新的function 回傳值 回傳值
不會立即執行 重複使用且不馬上執行 立即執行 直接用但不重複執行 立即執行 直接用但不重複執行
只會有this綁定的目標 僅一個參數 若傳複數個參數,用 []array type 也可以直接傳array 若傳複數個參數 用 , 隔開

關於 apply / bind / call 補充
https://youtu.be/c0mLRpw-9rI

又或是使用 arrow function 來取代 normal function ,因為在 arrow function 中 this 不會被重新定義 ,也就是 personA.printNameArrow() 的狀態

如果還對 this 意猶未竟、念念不捨的話,可以繼續深入以下的補充資料:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

js 的簡略複習到此告一段落
那麼 明天正式進入 React 的章節囉


上一篇
react 大冒險-快速複習 js 的語法 day 3
下一篇
react 大冒險-React 究竟是什麼-day 5
系列文
為期 30 天的 react 大冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言