顯示廣告
隱藏 ✕
※ 本文為 terievv 轉寄自 ptt.cc 更新時間: 2017-02-26 06:57:25
看板 Ajax
作者 eight0 (人類)
標題 Re: [問題] Hoisting 問題
時間 Sun Feb 19 23:24:23 2017


我覺得原 PO 的問題可能不是 hoisting,而是不知道 test = ... 會把 function test
覆蓋掉。不過這篇還是講 hoisting。

Hoisting 這個「行為」是被人「觀察」出來的。以 C 為例子︰

        #include <stdio.h>
        int a = 1;
        int main() {
                printf("%d\n", a);
                int a = 2;
                printf("%d\n", a);
        }

得到的結果會是

        1
        2

但在 JavaScript 中

        var a = 1;
        function main() {
                console.log(a);
                var a = 2;
                console.log(a);
        }
        main();

得到的結果是

        undefined
        2

人們就給出一套解釋︰「以 var 定義的變數,會被提到 function scope[1] 的最上面,
而且初始值是 undefined。並且會等到原本的位置(a = 2)才會賦值」,稱為
「Hoisting」。(其實這個說法是錯的,在定義 var 時並所謂的「初始值」並不一定是
 undefined,可能該變數本來就在 scope 內,或是被 function arguments 賦值)

[1]: 關於 scope: https://is.gd/tcHqDy
block - JavaScript | MDN
[圖]
A block statement (or compound statement in other languages) is used to group zero or more statements. The block is delimited by a pair of curly brack ...

 

事實上 JS 做的事情是︰在進入一個新的 scope 的時候,會把 var, function,
const, let 的變數收集起來,並且把變數名稱註冊到目前的 scope 中,接著才開始執行
接下來的程式碼。


它們之前的差別︰

var 是丟到 function scope,並且可以重覆定義,在未賦值前存取會得到 undefined。

function 也是丟到 function scope,可以重覆定義。若定義是放在 scope 的最外層

(定義位於 function scope 底下,而且不在任何 block scope 內),則會提前賦值,
所以你可以在 function 定義前就使用這個變數。否則就和 var 相同,在未賦值前存
取會得到 undefined。

const 和 let 是丟到 block scope,不能重覆定義,在還未賦值前存取會
ReferenceError。

const 還有一個限制是不能重覆賦值。


至於 const, let 也有 hoisting 現象,解釋為「將定義提升到 block scope 的最上
方,但若提前存取會丟出 ReferenceError」,並使用 temporal dead zone 的概念。
要解釋這個的話又和 function 的 default parameter 或 for, while 有關……


這裡解釋得滿清楚的︰
http://exploringjs.com/es6/ch_variables.html

如果看了這一堆還很有興趣的話,可以玩這個︰
http://perfectionkills.com/javascript-quiz-es6/
Javascript quiz. ES6 edition. — Perfection Kills
Javascript rants and findings, by kangax ...

 

--
                                      ▏                                      
                                      ▏                                      
                                   ◣                                  
                                  ▄▆                                
                                  ◥    ◤                                
                                   ▄                                         

--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.250.156.252
※ 文章代碼(AID): #1OgRYik4 (Ajax)
※ 文章網址: https://www.ptt.cc/bbs/Ajax/M.1487517868.A.B84.html
violet90079: 感謝指點~~JavaScript真的好深奧啊Orz1F 02/19 23:58
MangoTW: 推精闢解析2F 02/20 00:25
broo: 多謝解說!有了解一些了!3F 02/20 23:48

--
※ 看板: terievv 文章推薦值: 0 目前人氣: 0 累積人氣: 100 
分享網址: 複製 已複製
r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇