JavaScript 跟你想得不一樣(一)

寫 JavaScript 的你,會不會常常踩到這些地雷呢?

JavaScript 常常會被人誤解為是簡單的語言,以我自己的經驗,如果有人跟你說 JavaScript 很簡單,那一定是他不熟 JavaScript,會造成這個現象,最主要的原因是大多數的程式開發者都不是學 JavaScript 出身的(我也不是),所以開發者常常會把自己在其它語言的習慣帶過來,於是很多誤會就此而生.....(JavaScript 是很 nice 的,這其中一定有什麼誤會....)

變數 scope 是根據 function 不是 block

想像一下這段程式碼:

var a = 1;
if (true) {
var a = 2;
}
alert(a);

你覺得 alert 跳出來的訊息視窗會顯示什麼呢?答案是2。如果你太習慣 C/C++/Java, ..... 這類知名的程式語言,說不定你會回答1

所以如果是這個例子你就不會答錯了:

var a = 1;
function foo() {
var a = 2;
}
foo();
alert(a);

沒錯!答案就是1,但如果是這樣呢?

var a = 1;
function foo() {
alert(a);
}
foo();

別想太多,這段 code 的執行結果當然會跳出1。那如果變成這樣呢?

var a = 1;
function foo() {
alert(a);
var a = 2;
}
foo();

感覺要瘋掉了嗎? XD

不只是 Global 很可怕,window 物件也是

在瀏覽器上寫 JavaScript 或多或少都會用到 window 物件下的成員,但很可怕的是你常常不知道你在用它,因為使用 window 物件下的成員,window 是可以省略不打的。比方說很多人愛用 alert 來顯示訊息或 debug,但其實 alert 的「全名」應該是叫 window.alert 才對,喔!當然 location 也是叫 window.location,同樣地,你也不要不宣告就直接使用 innerWidth 這個變數 ..... 所以說 window 真的很可怕!!

但可怕的還不只是這樣,如果有一段 code 是這樣:

x = 3;
....
alert(window.x);

也許你(不)知道:在使用一個變數時,若沒用 var 這個關鍵字,它會被定義在 window 物件下,所以上面這段 code 當然沒有問題,x 就是 window.x,執行一下也沒錯,就是跳個訊息對話盒顯示3

那如果你很乖地加了 var 呢?變成這樣:

var x = 3;
....
alert(window.x);

嘿嘿,我就說 window 很可怕吧!只要你在 global area 下,就算用了 var 也幫你定義到 window 物件下!這也就是為什麼很多人寫 JavaScript code 會用一個 anonymous function 來避開 global/window 了。

(function(){
var x = 3;
....
alert(window.x); // undefined
})();

所以說,JavaScript 真的跟你想得不一樣!