JavaScript 可算是世界上最受歡迎的程式語言,它曾被Web 開發設計師貼上噩夢的標籤,雖然真正的噩夢其實是DOM API,這個被大量的開發與設計師隨手拈來增強他們的Web 前端的腳本語言,如今越來越被重視,雖則如此,JavaScript 仍然擁有很多讓人費解的東西。
1. 它以Java 命名,但並不是Java
它最初叫Mocha, 接著改名為LiveScript,最後才確定命名為JavaScript,根據歷史記錄,Java 的命名與Netscape 和Sun 之間的合作有關,作為交換條件,Netscape 在他們備受歡迎的瀏覽器中創建了Java 運行時。值得一提的是,這個名字的出台幾近一個玩笑,要知道,LiveScript 和 Java 在客戶端腳本方面存在敵對關係。
不管怎麼說,人們後來不得不一再澄清的一件事就是,JavaScript 和 Java 毫無關係。
2. Null 是個物件?
看看這段程式碼,它回傳的是 object。
這實在令人費解,假如 null 表示空值,它怎麼可以是物件?簡單說,它是 JavaScript 最初版本的錯誤,這個錯誤甚至被微軟的 JScript 直接借用。
3. NaN !== NaN
NaN,表示一個非數字的值,然而問題是,NaN不等於任何東西,甚至不等於它自己。
這顯然不對,事實上,如果要判斷一個值確實是 NaN,你需要用 isNaN() 函數。
4. 全域變數
對全域變數的依賴一直被視為 JavaScript 最壞的部分(ECMA 的 JavaScript 5 已經去掉了全域變量,請參閱 ECMA 推出 JavaScript 5 - 譯者註)。對簡單的頁面,這無所謂,但複雜的頁面,如果包含大量 JavaScript 腳本,你很難知道某個全域變數是在哪裡聲明的,如果幾個全域變數不小心重名,就會引發錯誤。
5. 那些統統被探測為 Mozilla User-Agent 的瀏覽器
必須承認,事實上,這不是 JavaScript 的錯,是各個瀏覽器有意為之。例如,以下是用JavaScript 探測Safari 時得到的結果:
是否注意到其中的第一個單字Mozilla/5.0,為什麼Safari 會被偵測為Mozilla,儘管Safari 後來已經修正這個問題,但仍然不能解釋為什麼它們要這樣誤導開發者。事實上,你會發現,絕大多數瀏覽器把他們的 User Agent 設定為 Mozilla,答案要回到10年前,這比較是一種策略。
User Agent 是一段用來識別當前瀏覽器身分的字串,世界上第一個瀏覽器Mosaic, 曾經這樣標誌自己:
這很合理,因此當Netscape 出來的時候,它保留了Mosaic 這個傳統,還在後面新增了一個加密方式部分。
到目前為止,一切安好,直到IE3 發布,當IE3 發布的時候,Netscape 正如日中天,那時,很多伺服器和程式已經部署了客戶端探測機制,以便認出Netscape,雖然現在看來,這很值得爭議,但當時並沒什麼。當IE 初次推出它們的User Agent 標誌的時候,是這個樣子:
這讓IE 很被動,因為Netscape 已經能被很多伺服器識別,因此,開發者們乾脆希望IE 被誤認為Mozilla,然後,再單獨加上一個IE 的標籤。
如今,幾乎所有瀏覽器都步 IE 後塵,將自己標識為 Mozilla,這大概是一種連鎖反應。
6. 不一致的函數範圍
參考以下程式碼:
foo(bar.method) 返回結果不同原因是,method 函數是被當作 windows 對象,而不是 bar 下的對象調用的。要解決這個問題,我們必須從傳遞的匿名函數中呼叫 bar.method() 。
7. 位元運算子
JavaScript 和 Java 有不少共同之處,如位元操作。
• & - and
• | - or
• ^ - xor
• ~ - not
• >> - signed right shift
• ??? - unsigned rightift
• & 運算符,使用&& 應該更有效,因為 JavaScript 和Java 不一樣,JavaScript 沒有整數,需要來回轉換,因此,轉換操作花的時間更長。
8. 太多的空值類型
諸如 null, false, undefined 一類的值幾乎表示同樣的意思,它們之間的不同又讓人很迷惑。
9. 算術問題
雖然 JavaScript 包含很多算術操作,但你不妨運行一下下面的算術問題,".2+.4" 應該等於 ".6" 是不是,然而返回的確是 "0.6000000000000001"。 JavaScript 在小數計算存取存在一些小問題。
為什麼會這樣?簡單說,因為JavaScript 使用IEEE 標準進行二進位浮點運算,不過,對整數計算是沒問題的。
10. 莫名其妙的代碼錯誤
看看以下兩段代碼:
它們應該是一樣的,只是{ 位置不同而已,對吧。然而我們再看下面的程式碼:
如果我們把其中的
換成
就會引發錯誤,這是因為JavaScript 有一個功能書寫,它會自作聰明地在return 這個字後面插入一個";" ,錯誤因此而生。