續上一篇文章,寫到後面還有一些觀念沒有講得很清楚,像是var
有Hoisting
的特性,coding的時候常出現的undefined
、not defined
,今天一次把它搞懂。
中文翻譯是提升,網路有些文章對此的解釋是JavaScrip
的變數和函示式,被提升到程式碼最上面,這樣的解釋好像還是不太理解,動手寫一段吧
var a = 'hello JavaScript!!';
function b(){
console.log('console b');
}
console.log(a);
b();
預期console.log結果會跑出:
"hello JavaScript!!"
"console b"
這沒有問題,接下來把code改成這樣呢:
console.log(a);
b();
var a = 'hello JavaScript!!';
function b(){
console.log('console b');
}
console.log結果:
undefined
"console b"
接下來我們把var a = 'hello JavaScript!!'給註解掉:
console.log(a);
b();
//var a = 'hello JavaScript!!';
function b(){
console.log('console b');
}
console.log結果變成:
Uncaught ReferenceError: a is not defined
這個現象稱為 Hoisting
。
以上都聽不懂很正常,接下來用其他方式講解
圖1.我們撰寫的JavaScript:
console.log(a);
b();
var a = 'hello JavaScript!!';
function b(){
console.log('console b');
}
console.log(a);//undefind
console.log('console b')//'console b'
經過JavaScript編譯,電腦看到的程式碼:
function b(){
console.log('console b');
}
var a;
console.log(a);
b();
a = 'hello JavaScript!!';
var a
進行宣告時把a
這個變數存到記憶體裡面,JavaScript
對所有變數預設都會是undefind
,之後再給a
變數賦予'hello JavaScript!!'這個字串。
執行環境開始運作時,會有兩個階段第一個是創建階段(Execution Context is Created)
:設定變量和函數在記憶體這個步驟就叫做Hoisting
,並不是真的把程式碼移到最上面,代表要逐步執行程式之前,JavaScript就已經把變數
和函式
放在記憶體裡建立一個空間,但是變數
有點不一樣,當出現var a = 'hello JavaScript!!';(圖1)等號符號被設定時,JavaScript再為a空出一個記憶體時他不知道等號後面是什麼,所以預設會直接給他undefind這個特殊值
。
JavaScript:
var a = 1;
console.log(a);// 1
//var a = 1;
console.log(a);// a not defined
依照剛剛複習的觀念,創建階段時並未宣告var a = 1
,所以a變數從來沒有出現在記憶體中,a not defined
就像是Browser
裡的JavaScript
跟你說:「 嘿,我沒有在`記憶體找到a這個值!」。
var a;
console.log(a);//undefined
當我們宣告var a
,a
在創造階段就會被放到記憶體中,並且JavaScript
會直接賦予undefined
給a
,所以undefined不代表空或是還沒定義
,undefined是個特殊的值,也會佔據記憶體空間。
開發時請記得不要把變數設值為undefind
:
var a = 'hello world!!';
console.log(a); //hello world!!
a = undefined;
console.log(a); //a = undefined
當程式碼變多時,你會無法分辨undefined
是JavaScrip
預設給的,還是你後來自己設定的。
##結論
undefined
不等於not defined
undefined``是已經宣告變數了
,JavaScript給的預設值。not defined
是創建環境時,沒有宣告加入記憶體
,JavaScript找不到這個值。