Re: [問題] Hoisting 問題

作者: eight0 (欸XD)   2017-02-19 23:24:23
我覺得原 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
事實上 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/
作者: violet90079 (ˊ__>ˋ)   2017-02-19 23:58:00
感謝指點~~JavaScript真的好深奧啊Orz
作者: MangoTW (不在線上)   2017-02-20 00:25:00
推精闢解析
作者: broo (陳爺)   2017-02-20 23:48:00
多謝解說!有了解一些了!
作者: kaidouya (今夜不回家)   2017-04-02 12:12:00

Links booklink

Contact Us: admin [ a t ] ucptt.com