React 初心者大補帖(1)

為什麼 const 可以在宣告前使用

在開發 React Component 或 Hook 時,常會看到像這樣的程式碼:

這看起來像是違反了 JavaScript 的規則,因為你在宣告 someStrategy 之前就用了它,但實際上這是合法的行為,也是 JavaScript 的預期表現。

一般來說,我們會在學習 JavaScript 的過程中看到這件事情:在 JavaScript 中,使用 const 或 let 宣告的變數不能在宣告之前被使用,否則會拋出 ReferenceError,這段期間稱為 TDZ(Temporal Dead Zone,暫時性死區)。

也就是說,如果你在變數「初始化之前」就嘗試使用它,JS 會拒絕執行:

所以我們直覺上會認為:

變數宣告在下面,上面就不該能用了吧?

但實際上,在 React 函式(或 Hook)中這種結構是合法的,讓我們一起看下去吧。

React 並沒有魔法

看起來在 React 中很神奇的事情,其實背後還是離不開 JavaScript 原本的行為。讓我們先來看看兩件事情的運作:Hoisting & 函式延遲執行(Deferred Execution)。

1. 模組層級的 Hoisting(提升)

在 ES Module 中,所有頂層的變數(const、let、var)、函式(function)在解析階段都會被「提升(hoist)」,意思是:JavaScript 會先掃描整個模組,把變數名稱、函式簽名都「先登記起來」。

不過 const/let 會處在 Temporal Dead Zone(暫時性死區,TDZ) 中,直到程式執行到那行才初始化。因此:

2. 函式是延遲執行(Deferred Execution)

在 JavaScript 中,函式的「定義」和「執行」是兩回事。

當 JS 解讀一段程式時,它會先記住你定義了哪些函式,但不會馬上執行它們,直到你主動「呼叫」它們為止。

舉個例子:

在 React 裡也是一樣,useHello 是一個函式,它的內容直到被呼叫時才會執行。因此即使 strategy 使用了尚未「寫到」的 helloStrategy,只要函式呼叫的時候 helloStrategy 已經初始化完,就不會有問題。

綜合以上兩點,我們可以理解到 React 並沒有魔法,在 const 定義前先呼叫並使用 const 的值是 JavaScript 裡正常的行為,只是因為 模組先執行、函式後呼叫 所帶來的結果。

Built with Hugo
Theme Stack designed by Jimmy