本文轉(zhuǎn)載于稀土掘金技術(shù)社區(qū),作者:情欲
1. JavaScript 為什么有設(shè)計缺陷?
這里有三個主要原因?qū)е铝?JavaScript 的設(shè)計不夠完善。
1.1. 設(shè)計時間過短
相信大家都知道 JavaScript 誕生就只花了十天,雖然這讓我們感到非常吃驚,感嘆設(shè)計者的能力之強大。但是從另一個角度想,沒有經(jīng)過深思熟慮的東西一定就有沒有考慮到的地方。相信大家在使用時也發(fā)現(xiàn)了 JavaScript 的一些缺陷。
我們程序猿一般都是給別人打工,很少是自己開發(fā)一個程序并且能夠自給自足的,JavaScript 的設(shè)計者也是這樣,也是為了給公司交差,本人并不想這樣設(shè)計。
另外,JavaScript 的設(shè)計初衷是為了實現(xiàn)一些網(wǎng)頁的簡單互動(比如:檢查用戶名是否填寫),并沒有考慮到現(xiàn)今的復雜應(yīng)用的開發(fā)。JavaScript 的設(shè)計者做夢也想不到 JavaScript 將來能寫出如今這么極其龐大復雜的網(wǎng)頁。
1.2. 過早的標準化
JavaScript 的發(fā)展太快了,甚至快到根本沒有時間進行調(diào)整設(shè)計。
1995年5月,設(shè)計方案定稿;10月,解釋器開發(fā)成功;12月,向市場推出,立刻被廣泛接受,全世界的用戶大量使用。Javascript缺乏一個從小到大、慢慢積累用戶的過程,而是連續(xù)的爆炸式擴散增長。大量的既成網(wǎng)頁和業(yè)余網(wǎng)頁設(shè)計者的參與,使得調(diào)整語言規(guī)格困難重重。
更糟的是,Javascript的規(guī)格還沒來及調(diào)整,就固化了。
1996年8月,微軟公司強勢介入,宣布推出自己的腳本語言Jscript;11月,為了壓制微軟,網(wǎng)景公司決定申請Javascript的國際標準;1997年6月,第一個國際標準ECMA-262正式頒布。
也就是說,Javascript推出一年半之后,國際標準就問世了。設(shè)計缺陷還沒有充分暴露就成了標準。相比之下,C語言問世將近20年之后,國際標準才頒布。
1.3. 沒有先例
JavaScript 很可能是第一個將函數(shù)式編程和面向?qū)ο缶幊探Y(jié)合的編程語言。而且到今天為止,JavaScript 仍然是世界上唯一使用 Prototype 繼承模型的主要語言。這使得它沒有先例可以參考。
2. JavaScript 的設(shè)計缺陷
2.1. null 和 undefined
我們在接觸 JavaScript 時都會被告知 null 在設(shè)計時有一個 bug,就是 type null === "object"
。
null 屬于對象的一種,意思為該對象為空;undefined則是一種數(shù)據(jù)類型,表示未定義。
var obj;
foo == null; // true
foo == undefined; // true
foo === null; // false
foo === undefined; // true
2.2. 全局變量
Javascript的全局變量,在任何位置中都是可見的;任何一個函數(shù)內(nèi)部都可以生成全局變量,這大大加劇了程序的復雜性。
function fn() {
n = 1; // 這里會創(chuàng)建全局變量
}
fn();
n; // 1
window.n; // 1
并且不用聲明變量就可以直接賦值。
let obj = {};
obj.name = "李華"; // 直接賦值即可創(chuàng)建變量
2.3. 自動插入行尾分號
Javascript的所有語句,都必須以分號結(jié)尾。但是,如果你忘記加分號,解釋器并不報錯,而是為你自動加上分號。有時候,這會導致一些難以發(fā)現(xiàn)的錯誤。
比如,下面這個函數(shù)根本無法達到預期的結(jié)果,返回值不是一個對象,而是 undefined。
function() {
return
{
i: 1;
};
}
原因是解釋器自動在 return 語句后買呢加上了分號。
function(){
return;
{
i:1
};
}
2.4. NaN
NaN 是一個數(shù)字,表示超出了解釋器的極限。它有一些奇怪的特性:
NaN === NaN; // false
NaN !== NaN; // true
2.5. == 和 ===
== 用來判斷兩個值是否相等。當兩個值類型不同時會發(fā)生自動轉(zhuǎn)換,得到的結(jié)果不符合直覺。
"" == "0"; // false
0 == ""; // true
0 == "0"; // true
false == "0"; // true
false == null; // false
false == undefined; // false
" \t\r\n" == 0; // true
因此推薦任何時候都使用 === 精確判斷比較符。
2.6. 更多缺陷
更多缺陷請查看:wtfjs.com[1]
3. 如何看待這些缺陷
JavaScript 既然有這么多缺陷,那它是不是會被淘汰?在七八年前我們可能會有這種擔憂,但在現(xiàn)在我們已經(jīng)看到了它的未來。它的能力很強大,既能編寫前端,又能編寫后端,既能編寫桌面應(yīng)用,也能編寫移動端應(yīng)用。甚至在任何角落我們都能看到它的身影。
JavaScript 的第三方庫也非常龐大,再加上良好的編程規(guī)范,就能回避大部分的缺陷。
另外 JavaScript 是目前網(wǎng)頁編程的唯一語言,只要互聯(lián)網(wǎng)繼續(xù)發(fā)展,它就必然發(fā)展。目前,許多新項目大大擴展了它的用途,node.js[2]使得Javascript可以用于后端的服務(wù)器編程,coffeeScript[3]使你可以用python和ruby的語法,撰寫Javascript。
最后,只要發(fā)布新版本的語言標準(比如 ECMAscript 5[4]),就可以彌補這些設(shè)計缺陷。當然,標準的發(fā)布和標準的實現(xiàn)是兩回事,上述的很多缺陷也許會一直伴隨到Javascript存在的最后一天。
該文章在 2024/3/30 0:16:22 編輯過