JS 簡史
Web 的興起已經(jīng)把 JavaScript 帶到一個前所未有的地步, 了解JS 的歷史更好的使用JS
一切的開始
一切都發(fā)生在 1995 年 5 月到 11 月這六個月內(nèi)昧互。網(wǎng)景通訊公司在早期的 Web 中擁有強(qiáng)大的地位。它的瀏覽器 Netscape Communicator砰左,作為第一款流行 Web 瀏覽器 NCSA Mosaic 的競爭對手,正獲得廣泛認(rèn)同誓篱。網(wǎng)景是由 90 年代早期參與 Mosaic 開發(fā)的同一伙人創(chuàng)立的皮壁,而現(xiàn)在,有了錢和獨(dú)立铣揉,他們就有了尋求進(jìn)一步擴(kuò)展 Web 的途徑所需的自由饶深。而這種自由催生了 JavaScript。
網(wǎng)景通訊的創(chuàng)始人及前 Mosaic 團(tuán)隊的成員 Marc Andreessen 預(yù)見到 Web 需要某種方法變得更動態(tài)逛拱。動畫敌厘、交互和其它形式的小動畫應(yīng)該是未來 Web 的一份子。所以 Web 需要一種能與 DOM 交互(它跟現(xiàn)在一樣朽合,不是一成不變的)的小腳本語言俱两。不過,在當(dāng)時這是一種重要的戰(zhàn)略叫法曹步,這種腳本語言不應(yīng)該面向大佬開發(fā)者宪彩,以及在軟件工程方面有經(jīng)驗的人們。當(dāng)時 Java 也在興起讲婚,并且 Java applets 很快就要成為現(xiàn)實尿孔。所以這個用于 Web 的腳本語言需要迎合不同類型的受眾:設(shè)計師。實際上,那是 Web 是靜態(tài)的活合。HTML 依然年輕雏婶,并且足夠簡單,非程序員也很容易學(xué)會白指。所以留晚,要讓 Web 變得更動態(tài),不管是瀏覽器的哪一部分告嘲,都應(yīng)該讓非程序員容易理解错维。這樣 Mocha 的想法就誕生了。Mocha 要成為用于 Web 的一種腳本語言状蜗,它必須是簡單需五、動態(tài)的,并且讓非程序員容易理解轧坎。
此時宏邮,JavaScript 之父 Brendan Eich 被卷進(jìn)來了。網(wǎng)景通訊公司雇傭 Eich缸血,是讓他開發(fā)一種 "用于瀏覽器的 Scheme"蜜氨。Scheme 是一種 Lisp 的方言,語法很簡單捎泻,它動態(tài)而強(qiáng)大飒炎,并且本質(zhì)上是函數(shù)式的。而 Web 需要類似這樣的語言:語法容易掌握笆豁;動態(tài)的郎汪,以減少冗長,加快開發(fā)闯狱;并且強(qiáng)大煞赢。Eich 看到有機(jī)會可以從事自己喜歡的事情,于是就入伙了哄孤。
祖師爺Brendan Eich
當(dāng)時照筑,迫于壓力,必須盡快趕出一個工作原型瘦陈。當(dāng)時原名為 Oak 的 Java 語言正開始推動凝危。Sun Microsystems 正大力推進(jìn) Java,網(wǎng)景通訊公司即將與他們達(dá)成一項協(xié)議晨逝,讓 Java 可以用在瀏覽器上蛾默。那么為什么要開發(fā) Mocha(Mocha 是 JavaScript 早期的名字)呢?為什么已經(jīng)有了 Java咏花,卻還要開發(fā)一個全新的語言呢趴生?當(dāng)時的想法是阀趴,Java 不適合于會使用 Mocha 的一類受眾:測試腳本編寫人員、業(yè)余愛好者苍匆、設(shè)計師刘急。對于用在瀏覽器這個角色上來說,Java 確實太大太重了浸踩。所以當(dāng)時他們的想法是讓 Java 用于大型專業(yè)級組件開發(fā)叔汁;而 Mocha 將用于小型腳本任務(wù)。也就是說检碗,Mocha 命中注定就是 Java 的腳本同伴据块,在某種程度上類似于 Windows 平臺上 C/C++ 和 Visual Basic 之間的關(guān)系。
與此同時折剃,網(wǎng)景的工程師開始詳細(xì)地研究 Java另假。他們甚至開始開發(fā)自己的 Java 虛擬機(jī)。不過怕犁,這個虛擬機(jī)很快被否決边篮,因為它從來就沒有實現(xiàn)與 Sun 的虛擬機(jī)的完美一致关拒。
此時有很多來自于內(nèi)部的壓力劳坑,要盡可能快地選擇一門語言乍丈。Python虱痕、Tcl 以及 Scheme 本身都是可能的候選。所以椿浓,Eich 必須搞快凑兰。不過闹啦,他比可選方案有兩個優(yōu)勢:可以自由挑選適合的特性集挠进、可以直達(dá)拍板的人色乾。不幸的是,他也有一個大的劣勢:沒有時間领突。必須要做出很多重要的決定杈湾,而做出決定的可用時間又很短。JavaScript攘须,即 Mocha,就是在這種背景下誕生的殴泰。幾周之內(nèi)于宙,一個工作原型就推出了,然后就被集成到 Netscape Communicator 中悍汛。
于是捞魁,本應(yīng)是用于瀏覽器的 Scheme,現(xiàn)在就大相徑庭了离咐。與 Sun 達(dá)成協(xié)議的壓力谱俭,以及讓 Mocha 變成 Java 的腳本同伴奉件,束縛住了 Eich 的手腳。新語言需要采用類似 Java 的語法昆著,對于很多常用語還采用了熟悉的語義县貌。所以 Mocha 一點(diǎn)也不像 Scheme。它表面上看像是一種動態(tài)的 Java凑懂,實際上卻是一個雜交品種:Scheme 和 Self 的早產(chǎn)私生子煤痕,長的像 Java。
1995 年 5 月接谨, Mocha 的原型被集成到 Netscape Communicator 中摆碉。很快,它被重命名為 LiveScript脓豪。當(dāng)時巷帝,"live" 這個單詞只是為了營銷方便。1995 年 12 月扫夜,網(wǎng)景通訊公司和 Sun 達(dá)成協(xié)議:Mocha/LiveScript 將被重新命名為 JavaScript楞泼,它將會作為瀏覽器中小型客戶端任務(wù)的一種腳本語言,同時 Java 將會被提升為一種更大的历谍、開發(fā)富 Web 組件的專業(yè)工具现拒。
第一版的 JavaScript 敲定了該語言中很多現(xiàn)在知名的特性,特別是其對象模型以及函數(shù)式特性在此版本中已經(jīng)出現(xiàn)了望侈。
如果當(dāng)時 Eich 未能按時趕出一個工作原型印蔬,很難說會發(fā)生什么。其他可選方案一點(diǎn)也不像 Java脱衙。Python侥猬、Tcl 和 Scheme 都與 Java 大不相同。對于 Sun 公司來說捐韩,很難接受一個與 Java 如此不同的同伴語言退唠,或者在歷史和開發(fā)上比 Java 本身早的語言。另一方面荤胁,Java 很長一段時間是 Web 的一個重要部分瞧预。如果 Sun 從沒有過這樣的地位,網(wǎng)景可能會在挑選這樣一個語言上有更多的自由仅政。這是肯定的垢油。不過,如果就算網(wǎng)景自己內(nèi)部能控制和開發(fā)圆丹,它會不會選擇采用外部的解決方案呢滩愁?我們將永遠(yuǎn)不會知道。
不同的實現(xiàn)
當(dāng) Sun 和 Netscape 達(dá)成協(xié)議辫封,將 Mocha/LiveScript 的名稱改為 JavaScript 時硝枉,有個大問題被提出來了:其他實現(xiàn)會怎么辦廉丽?實際上,盡管 Netscape 很快成為了當(dāng)時首選的瀏覽器妻味,不過微軟也正在開發(fā) Internet Explorer正压。從最開始,JavaScript 在用戶體驗上就有如此大的差異弧可,競爭的瀏覽器沒辦法蔑匣,只能想出一個可行的解決方案,就是自己整一套 JavaScript 的實現(xiàn)棕诵。此時(并且很長一段時間)裁良,Web 標(biāo)準(zhǔn)還不強(qiáng)大。所以微軟實現(xiàn)了自己版本的 JavaScript校套,叫做 JScript价脾。從名稱中去掉 “Java”,是為了避免潛在的商標(biāo)問題笛匙。不過侨把,JScript 不僅僅是名稱上的不同。它在實現(xiàn)上也略有不同妹孙,特別是與某些 DOM 函數(shù)有關(guān)的實現(xiàn)上有所不同秋柄,由此產(chǎn)生的影響一直波及到多年之后的未來。JavaScript 大戰(zhàn)還發(fā)生除了名稱和時間表之外的更多方面上蠢正,而它的怪癖正是這些大戰(zhàn)打來的創(chuàng)傷骇笔。JScript 的第一個版本包含在 1996 年 8 月發(fā)布的 IE 3.0 中。
網(wǎng)景的 JavaScript 實現(xiàn)也采用了一個內(nèi)部名稱嚣崭。和 Netscape Navigator 2.0 一起發(fā)布的版本被稱為 Mocha笨触。在 1996 年秋天,Eich 為了償還匆忙推出它所導(dǎo)致的技術(shù)債雹舀,將 Mocha 的大部分重寫為一個更干凈的實現(xiàn)芦劣。這個新版本的網(wǎng)景 JavaScript 引擎叫做 SpiderMonkey。SpiderMonkey 現(xiàn)在依然是 Netscape Navigator 的孫子 Firefox 中 JavaScript 引擎的名稱说榆。
有好幾年虚吟,JScript 和 SpiderMonkey 是主要的 JavaScript 引擎。二者所實現(xiàn)的并非總是兼容的功能签财,會定義接下來幾年中 Web 會成為什么樣子稍味。
主要設(shè)計特點(diǎn)
盡管 JavaScript 是倉促之間誕生的,不過有幾個強(qiáng)大的特性在開始就是它的一部分荠卷。這些特性將 JavaScript 定義為一門語言,盡管有各種怪癖烛愧,依然讓它能突破其圍墻花園油宜。
是使用一門已有的語言掂碱,還是發(fā)明一門新的語言,這也不是我能決定的慎冤。來自高層工程管理人員的強(qiáng)制命令是這門語言必須“看起來像 Java ”疼燥。這實際上也就把 Perl、Python蚁堤、 Tcl 以及 Scheme 這些已有的語言排除掉了醉者。后來,在 1996 年披诗,John Ousterhout 在給 Tk 做宣傳時還感嘆說撬即,Tcl 錯過了這樣一個很好的機(jī)會。我并非驕傲呈队,只不過是很高興我選擇 Scheme 式的一等函數(shù)以及 Self 式(盡管很怪異)的原型作為主要因素剥槐。至于 Java 的影響,主要是把數(shù)據(jù)分成基本類型和對象類型兩種(比如字符串和 String 對象)宪摧,以及引入了Y2K 日期問題,這真是不幸蕊苗。
類 JAVA 的語法
盡管讓 JavaScript 語法接近 Java 并非初衷沿彭,不過市場力量讓它變成了這樣朽砰。退一步想膝蜈,即使采用與 Java 不同的語法可能會讓實現(xiàn)某些特性更為方便,但是不可否認(rèn)饱搏,采用熟悉的語法更有助于 JavaScript 的普及非剃。
java
public class Sample {
public static void main(String[] args) {
System.out.println("Hello world!");
try {
final MissileSilo silo = new MissileSilo("silo.weapons.mil");
silo.launchMissile(args[0]);
} catch(Exception e) {
System.out.println("Unexpected exception: " + e);
}
}
}
js
console.log('Hello world');
try {
const silo = new MissileSilo('silo.weapons.mil');
silo.launchMissile(process.argv[0]);
} catch(e) {
console.log('Unexpected exception' + e);
}
函數(shù)作為一等對象
在 JavaScript 中备绽,函數(shù)只是又一個對象類型肺素。它們可以像任何其它元素一樣傳遞倍靡,可以被綁定到變量塌西。在稍后版本的 JavaScript 中,函數(shù)甚至可以被拋出為異常办桨。這個特性很有可能是在 JavaScript 開發(fā)時受到 Scheme 強(qiáng)烈影響的結(jié)果呢撞。
var myFunction = function() {
console.log('hello');
}
otherFunction(myFunction);
myFunction.property = '1';
// 通過讓函數(shù)變成一等對象殊霞,某些函數(shù)式編程模式才成為可能
var a = [1, 2, 3];
a.forEach(function(e) {
console.log(e);
});
基于原型的對象模型
盡管基于原型的對象模型是通過 JavaScript 得以流行的脓鹃,不過它卻是在 Self 語言中首次引入瘸右。Eich 對這種模型有種強(qiáng)烈的偏好岩齿,它足夠強(qiáng)大盹沈,能夠模仿像 Java 或 C++ 這種基于 Simula 的語言中的更傳統(tǒng)的方式乞封。實際上肃晚,JavaScript 之后的版本中實現(xiàn)的類关串,也只不過是在原型系統(tǒng)之上的語法糖晋修。
JavaScript 的原型靈感來自于 Self墓卦,而 Self 的設(shè)計目標(biāo)之一就是要避免 Simula 風(fēng)格的對象的問題。特別是山叮,在 Simula 的方式下,類和實例之間的對立被看到是很多固有問題的誘因暮胧。有人認(rèn)為往衷,因為類為對象實例提供某種原型席舍,隨著代碼演變和逐漸變大来颤,就越來越難讓這些基類適應(yīng)不可預(yù)料的新需求福铅。通過將實例成為新對象構(gòu)建的原型滑黔,這種限制就被克服了略荡。因此汛兜,原型的概念是:一個通過提供自己的行為序无,填補(bǔ)新實例的空白的實例帝嗡。如果一個原型被認(rèn)為不適合于一個新對象璃氢,那么它只需要被克隆和修改,而不會影響所有其它子實例喉脖。這在基于類的方式中是挺難做到的(即,修改基類)题诵。
function Vehicle(maxSpeed) {
this.maxSpeed = maxSpeed;
}
Vehicle.prototype.maxSpeed = function() {
return this.maxSpeed;
}
function Car(maxSpeed) {
Vehicle.call(this, maxSpeed);
}
Car.prototype = new Vehicle();
原型的威力讓 JavaScript 變得超級靈活性锭,引發(fā)了很多帶有自己對象模型的庫的開發(fā)草冈。一個流行的庫 Stampit 就重度使用了原型系統(tǒng)怎棱,采用在基于類的傳統(tǒng)方法下不可能的方式蹄殃,來擴(kuò)充和操作對象诅岩。
原型讓 JavaScript 看起來貌似簡單吩谦,但是給庫的作者帶來了自主權(quán)式廷。
大怪癖:基礎(chǔ)類型與對象
也許在匆忙開發(fā)的 JavaScript 中,最大的錯誤之一是某些行為類似的對象有不同的類型蠕趁。例如俺陋,字符串字面量("Hello world")的類型與 String 對象(new String('Hello world'))的類型就是不相同的腊状。這就讓我們有時候不得不采用不必要的缴挖、容易混淆的類型檢查映屋。
> typeof "hello world"
< "string"
> typeof new String('hello world')
< "object"
然而,在 JavaScript 歷史中埃仪,這只是個開始颁股。它的倉促開發(fā)讓某些設(shè)計失誤的可能性變得更為真實甘有。不過亏掀,有一種用于動態(tài) Web 的語言的優(yōu)點(diǎn)不能被推遲滤愕,其它的一切交給了歷史间影。
余下的是逆轉(zhuǎn)的魂贬、殘酷的歷史。JS 在客戶端戰(zhàn)勝了 Java机蔗,競爭的只有 Flash萝嘁,而 Flash 支持 JS 的后代 ActionScript
追憶往事:看看 Netscape Navigator 2.0 和 3.0
JavaScript 的第一個公開發(fā)行版被集成到 1995 年發(fā)布的 Netscape Navigator 2.0 中.
注意視頻中的錯誤是如何給我們發(fā)生什么事情的更多信息牙言。這讓我們推測解釋器以一種特殊的方式對待 prototype 屬性卑硫。于是我們嘗試用基礎(chǔ)的 Object 實例來替換對象欢伏,這樣我們之后就可以修改該對象硝拧。嗯障陶,好了抱究,搞定了!至少在某種程度上侄刽。test 函數(shù)內(nèi)的賦值貌似什么都沒做州丹。很顯然墓毒,還有很多工作需要去做所计。盡管如此叭首,這個狀態(tài)的 JavaScript 對于很多任務(wù)是可用的焙格,并且它的流行開始增長眷唉。
像正則表達(dá)式冬阳、JSON 和異常等特性此時依然不能用。在接下來的幾年中见坑,JavaScript 會迅猛發(fā)展。
ECMAScript: JavaScript 作為一個標(biāo)準(zhǔn)
JavaScript 公開發(fā)布后的第一次重大改變是以 ECMA 標(biāo)準(zhǔn)化的形式出現(xiàn)贯城。ECMA 是 1961 年成立的一個行業(yè)協(xié)會,該協(xié)會只從事信息和通訊系統(tǒng)的標(biāo)準(zhǔn)化踩晶。
JavaScipt 的標(biāo)準(zhǔn)化工作始于 1996 年 11 月渡蜻。標(biāo)準(zhǔn)號是 ECMA-262,負(fù)責(zé)的委員會是 TC-39学密。這時候腻暮,JavaScript 已經(jīng)是很多頁面的流行元素具垫。這份1996 年的新聞稿 說采用 JavaScript 的頁面數(shù)量已達(dá) 300,000做修。
JavaScript 和 Java 是開發(fā) Internet 和 Intranet 應(yīng)用程序的 Netscape ONE 平臺的基礎(chǔ)技術(shù)。自去年引入它們的很短一段時間內(nèi)燎含,新語言快速被開發(fā)者接受屏箍。根據(jù) www.hotbot.com 統(tǒng)計赴魁,在當(dāng)今互聯(lián)網(wǎng)上有 175,000 個新 Java 小程序和超過 300,000 個使用 JavaScript 的頁面。- Netscape 新聞稿
對于這樣一個年輕的語言來說潘拱,標(biāo)準(zhǔn)化是一個重要的步驟芦岂,不過依然是一個重大的號召。它將 JavaScript 開放給更廣泛的受眾弛随,并且給其它潛在的實現(xiàn)者在語言進(jìn)化上的發(fā)言權(quán)舀透。它還充當(dāng)了約束其它實現(xiàn)者的用途走贪。那時候坠狡,它擔(dān)心微軟或者其它人會偏離默認(rèn)的實現(xiàn)太遠(yuǎn),從而導(dǎo)致分裂凯亮。
由于商標(biāo)的原因,ECMA 委員會不能用 JavaScript 做名字富拗,而其它名稱也有很多人不喜歡。所以經(jīng)過幾輪磋商后谅阿,決定這個用標(biāo)準(zhǔn)來描述的語言將被叫做 ECMAScript。現(xiàn)在,JavaScript 只是 ECMAScript 的商業(yè)名稱体捏。
ECMAScript 1 和 2:標(biāo)準(zhǔn)化的路上
第一個 ECMAScript 標(biāo)準(zhǔn)是基于 Netscape Navigator 4 發(fā)布的 JavaScript 版本,它依然缺失重要的特性年栓,比如正則表達(dá)式某抓、JSON汉矿、異常洲拇、以及內(nèi)置對象的重要方法。不過蚕捉,在瀏覽器中它工作的不錯迫淹。JavaScript 正開始變得越來越好。1997 年 6 月应民,版本 1 發(fā)布了。
Netscape Navigator 4
注意归园,視頻中那個簡單的原型和函數(shù)測試現(xiàn)在可以正常工作了。在 Netscape 4 中很多工作已經(jīng)在幕后完成了桥爽,而 JavaScript 從受益良多。現(xiàn)在我們的示例基本上可以與任何當(dāng)代瀏覽器運(yùn)行的一樣了昧识。這對于 JavaScript 第一次發(fā)布成一個標(biāo)準(zhǔn)來說钠四,是一個很好的局面。
標(biāo)準(zhǔn)的第二版 ECMAScript 2 的發(fā)布是用來糾正 ECMA 和 JavaScript ISO 標(biāo)準(zhǔn)(ISO/IEC 16262)之間的不一致性的跪楞,所以語言沒有做任何改動形导。這個版本發(fā)布于 1998 年 6 月。
此版本的 JavaScript 的一個有趣的怪癖是朵耕,在編譯時沒有被捕獲的錯誤(這通常是留作為未確定的)交給解釋器任意決定如何處理炫隶。這是因為異常還不是該語言的一部分。
ECMAScript 3:第一次大變動
ECMAScript 2 后工作在繼續(xù)阎曹,對該語言的第一次大變更出現(xiàn)了伪阶。這個版本帶來了:
- 正則表達(dá)式
- do-while 塊
- 異常和 try/catch 塊
- 更多有關(guān)字符串和數(shù)組的內(nèi)置函數(shù)
- 格式化數(shù)字輸出
- in 和 instanceof 運(yùn)算符
- 更好的錯誤處理
ECMAScript 3 發(fā)布于 1999年 12 月。
這個版本的 ECMAScript 流傳甚廣处嫌。它被當(dāng)時的所有主流瀏覽器所支持栅贴,而且多年后一直支持。即使到了今天熏迹,有些轉(zhuǎn)譯器依然可以在產(chǎn)生輸出時檐薯,以這個版本的 ECMAScript 為目標(biāo)。這讓 ECMAScript 3 成為了很多庫的基準(zhǔn)目標(biāo)注暗,即使后來版本的標(biāo)準(zhǔn)發(fā)布了也是如此坛缕。
即使 JavaScript 越來越流行,它依然主要是一種客戶端語言捆昏。不過赚楚,它很多新特性讓它離打破這種牢籠更近。
2000年 11 月骗卜,Netscape Navigator 6 發(fā)布宠页。這個版本是對過去版本的重大修訂,支持 ECMAScript 3寇仓。大約在一年半后举户,F(xiàn)irefox 發(fā)布。它是一個基于 Netscape Navigator 代碼庫的精簡版瀏覽器遍烦,也支持 ECMAScript 3俭嘁。這些瀏覽器與 IE 一起,繼續(xù)推動 JavaScript 的成長乳愉。
AJAX 的誕生
AJAX,即異步 JavaScript 和 XML屯远,是一種在 ECMAScript 3 年代誕生的技術(shù)蔓姚。雖然它并非標(biāo)準(zhǔn)的一部分,不過微軟為其 IE5 瀏覽器實現(xiàn)了某些對 JavaScript 的擴(kuò)展慨丐。其中之一就是 XMLHttpRequest 函數(shù)(以 XMLHTTP ActiveX 控件的形式)坡脐。該函數(shù)允許瀏覽器執(zhí)行對服務(wù)器的異步 HTTP 請求,從而允許頁面被即時動態(tài)更新房揭。雖然術(shù)語 AJAX 直到幾年后才被創(chuàng)造出來备闲,但是這種技術(shù)早就到處在用了晌端。
術(shù)語 AJAX 是由 Adaptive Path 的聯(lián)合創(chuàng)始人 Jesse James Garrett 在這篇標(biāo)志性博客中創(chuàng)造出來的。
XMLHttpRequest 被證明是非常成功的恬砂,多年以后被集成到一個單獨(dú)的標(biāo)準(zhǔn)中(作為 WHATWG 和 W3C 組織的一部分)咧纠。
由實現(xiàn)者給語言帶來一些有趣的東西,并且在瀏覽器中實現(xiàn)泻骤,從而促進(jìn)特性的發(fā)展漆羔,依然是 JavaScript 和相關(guān)的 Web 標(biāo)準(zhǔn)(比如 HTML 和 CSS)繼續(xù)發(fā)展的方式。不過狱掂,那時不同派系之間溝通極少演痒,導(dǎo)致拖延和分裂。憑心而論趋惨,有了任何感興趣的派系提出建議的程序鸟顺,今天的 JavaScript 開發(fā)顯得更有組織。
玩玩 NETSCAPE NAVIGATOR 6 Netscape Navigator 6
這個版本支持異常器虾,之前版本在試圖訪問 Google 時候遇到的主要缺陷讯嫂。不可思議的是,即使在今天曾撤,試圖在這個版本中訪問 Google端姚,也會一個看得見的工作頁面。相比之下挤悉,如果試圖用 Netscape Navigator 訪問 Google渐裸,就會被缺乏異常、不完整的渲染以及糟糕的布局弄的焦頭爛額装悲。Web 正在快速發(fā)展昏鹃,即使在當(dāng)時。
玩玩 INTERNET EXPLORER 5 IE5
IE5 也能渲染當(dāng)前版本的 Google诀诊。不過洞渤,眾所周知,在實現(xiàn)某些特性上面属瓣,IE 和其它瀏覽器之間有很多分歧载迄。這些分歧禍害了 Web 很多年,也是長期以來 Web 開發(fā)者受挫之源抡蛙,因為他們經(jīng)常不得不為 IE 用戶實現(xiàn)特例护昧。
實際上,要在 IE5 和 IE6 中訪問 XMLHttpRequest 對象粗截,必須要借助于 ActiveX惋耙。其它瀏覽器將其實現(xiàn)為原生對象。
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
毫無疑問,是 IE5 率先將 AJAX 理念變成現(xiàn)實绽榛。不過湿酸,直到 IE7,微軟才開始遵循標(biāo)準(zhǔn)灭美,并更貼近共識推溃。有些老公司網(wǎng)站依然需要老版本的 IE 才能正確運(yùn)行。
ECMAScript 3.1 和 4:斗爭之年
不幸的是冲粤,隨后幾年對 JavaScript 開發(fā)是不利的美莫。從 ECMAScript 4 的工作一開始,委員會中就開始出現(xiàn)了強(qiáng)烈的分歧梯捕。有一群人認(rèn)為 JavaScript 需要一些特性來成為一種更強(qiáng)大的語言厢呵,這樣就可以用于大型應(yīng)用程序開發(fā)。這群人提出了很多特性傀顾,這些特性涉及面廣襟铭,變化大。另一群人認(rèn)為大型應(yīng)用程序開發(fā)不是 JavaScript 適合的方向短曾。由于缺乏一致意見寒砖,加上新提出的某些特性的復(fù)雜性,將 ECMAScript 4 的發(fā)布變得遙遙無期嫉拐。
實際上針對 ECMAScript 4 的工作在 1999 年 版本 3 剛出爐的時候哩都,就已經(jīng)開始了。網(wǎng)景公司內(nèi)部討論了很多有意義的特性婉徘。不過漠嵌,實現(xiàn)這些特性的興趣已經(jīng)逐漸減弱,并且 2003 年過沒多久盖呼,在新版本 ECMAScript 上的工作就停止了儒鹿。一個臨時報告發(fā)布了,有些實現(xiàn)者几晤,比如 Adobe(ActionScript)和微軟(JScript.NET)约炎,使用這個報告作為其引擎的基礎(chǔ)。2005 年蟹瘾,在 AJAX 和 XMLHttpRequest 的影響之下圾浅,再度激發(fā)了新版本 JavaScript 的興趣,TC-39 重啟了工作憾朴。幾年過去了狸捕,特性集變得越來越大。在 ECMAScript 4 開發(fā)的最高峰伊脓,有如下這些特性:
- 類
- 接口
- 命名空間
- 包
- 可選的類型注解
- 可選的靜態(tài)類型檢查
- 結(jié)構(gòu)類型
- 類型定義
- 多方法(Multimethods)
- 參數(shù)化類型
- 尾調(diào)用
- 迭代器(Iterator)
- 生成器(Generator)
- 內(nèi)省
- 類型識別的異常處理器
- 常量綁定
- 塊作用域
- 解構(gòu)
- 函數(shù)表達(dá)式
- 數(shù)組推導(dǎo)式(Array comprehensions)
ECMAScript 4 草案將這個新版本描述為編寫大型應(yīng)用程序而設(shè)計府寒。如果你已熟悉 ECMAScript 6/2015,就會注意到很多來自 ECMAScript 4 的特性被重新引入了报腔。
雖然 ES3 靈活株搔,并且在形式上很強(qiáng)大,但是在開發(fā)大型軟件系統(tǒng)實踐中纯蛾,它的抽象能力經(jīng)常是無法勝任的纤房。由于在 Web 上采用 Ajax 編程,在應(yīng)用程序中大量使用 ECMAScript 作為插件以及腳本語言翻诉,ECMAScript 程序正變得越來越大炮姨,越來越復(fù)雜。大型程序的開發(fā)可以從靜態(tài)類型檢查碰煌、名稱隱藏舒岸、早綁定以及其它優(yōu)化手段、直接支持面向?qū)ο缶幊痰燃夹g(shù)上大大受益芦圾,而這些都是 ES3 中所缺乏的蛾派。 - ECMAScript 4 草案
一則有趣的歷史片段是如下的 Google Docs spreadsheet,這個文件展示了幾種 JavaScript 引擎的實現(xiàn)狀態(tài)个少,以及涉及其中的派系的討論洪乍。
開發(fā) ECMAScript 4 的委員會由 Adobe、Mizilla夜焦、Opera(以非官方身份)和微軟組成壳澳。Yahoo 在大部分標(biāo)準(zhǔn)和特性已經(jīng)決定了后,進(jìn)入了這個委員會茫经。Doug Crockford巷波,一個有影響力的 JavaScript 開發(fā)者,就是 Yahoo 為此送進(jìn)委員會的那個人科平。他鼓吹他的擔(dān)憂褥紫,強(qiáng)烈反對很多 ECMAScript 4 提議的修改。他從微軟的代表那里獲得了強(qiáng)烈的支持瞪慧。Crockford 本人說到:
但是結(jié)果微軟的委員也有同樣的擔(dān)憂 - 他也認(rèn)為這門語言正變得太大髓考,失去了控制。在我加入委員會之前弃酌,他什么都沒有說氨菇,因為他擔(dān)心,如果微軟試著阻攔這件事妓湘,就會被指責(zé)為反競爭行為查蓉。根據(jù)微軟過去的表現(xiàn),也許他們有一些不錯的理由對此在意 - 并且很顯然榜贴,這些擔(dān)憂是有理有據(jù)的豌研,因為已經(jīng)發(fā)生過妹田。但是我勸他說,微軟應(yīng)該做正確的事情鹃共,并且以他的聲譽(yù)鬼佣,他決定他應(yīng)該,也能說服微軟霜浴。所以微軟就在 ES4 上改變了立場晶衷。 - Douglas Crockford — JavaScript 的現(xiàn)狀和未來
開始是懷疑,后來就變成強(qiáng)勢反對 JavaScript阴孟。微軟拒絕接受 ECMAScript 4 的所有部分晌纫,并且準(zhǔn)備采取各種必要的行動來阻止標(biāo)準(zhǔn)獲得通過(甚至法律訴訟)。幸運(yùn)的是永丝,委員會中的人設(shè)法阻止了法律斗爭锹漱。不過,缺乏共識有效地阻止了 ECMAScript 4 推進(jìn)慕嚷。
微軟的某些人想在這件事情上采取強(qiáng)硬手段凌蔬,他們想開始建立書面憑據(jù),開始走申訴程序闯冷,想做這些額外的法律程序欣尼。我可不想有這種事情版姑。我是不同意 ES4慎菲,但是僅限于技術(shù)層面唇兑,并且我想只限于技術(shù)層面;我不想讓它變得比以前更麻煩纺涤。我只是想搞清楚什么事情該做译暂,所以我設(shè)法溫和一點(diǎn)。但是微軟依然采取了極端立場撩炊,說他們拒絕接受 ES4 的任何部分外永。所以事情就變成了兩極分化,但是我認(rèn)為兩極分化是因為 ES4 團(tuán)隊拒絕考慮任何其它觀點(diǎn)的結(jié)果拧咳。那時委員會沒有達(dá)成共識伯顶,這是件糟糕的事情,因為標(biāo)準(zhǔn)小組必須要達(dá)成共識骆膝。一個標(biāo)準(zhǔn)不應(yīng)該是有爭議的祭衩。 - Douglas Crockford — JavaScript 的現(xiàn)狀和未來.
Crockford 想出一個點(diǎn)子來推進(jìn),就是重新弄一個標(biāo)準(zhǔn)阅签,這個標(biāo)準(zhǔn)更簡單掐暮,減少一些特性集,這樣所有人都可以同意:沒有新語法政钟,只有來自使用該語言的經(jīng)歷中的實際提升路克。這個提案后來被稱為 ECMAScript 3.1樟结。
有一段時間,兩種標(biāo)準(zhǔn)并存精算,并且設(shè)置了兩個非正式的委員會狭吼。不過,ECMAScript 4 太復(fù)雜殖妇,沒辦法在面對沖突的情況完成。ECMAScript 3.1 更簡單破花,并且盡管在 ECMA 中有斗爭谦趣,它還是完成了。
ECMAScript 4 的結(jié)束出現(xiàn)在 2008 年座每,Eich 通過一封電子郵件前鹅,發(fā)送了一次奧斯陸會議的內(nèi)容提要,詳細(xì)描述了 ECMAScrpt 走向和版本 3.1 和 4 的未來峭梳。
- 與所有各方充分合作舰绘,集中精力完成 ES 3.1,到明年初確定兩個執(zhí)行標(biāo)準(zhǔn)葱椭。
- 下一步上的合作超出 ES3.1捂寿,會包含語法上的擴(kuò)展,但是會在語義和語法創(chuàng)新上比 ES4 更謹(jǐn)慎孵运。
- 有些 ES4 提案已經(jīng)被認(rèn)為對 Web 不合理秦陋,最好不予討論:包、命名空間和早綁定治笨。這個結(jié)論對于 Harmony 來說很關(guān)鍵驳概。
- ES4 的其它目標(biāo)和理念正被改寫,以保持在委員會中的一致旷赖;包括類的概念是基于已有的 ES3 概念結(jié)合提議的 ES3.1 擴(kuò)展顺又。
總之,ECMAScript 4 花了近 8 年的時間開發(fā)等孵,最后卻被廢棄了稚照。這對涉及的所有人來說都是一個沉重的教訓(xùn)。
單詞 "Harmony(和諧)" 出現(xiàn)在上面的結(jié)論中俯萌。這是將來對 JavaScript 擴(kuò)展時項目的標(biāo)準(zhǔn)名稱锐锣。Harmony 會是所有人都同意的方案。在 ECMAScript 3.1 發(fā)布后(以版本 5 的形式绳瘟,下面我們會看到)雕憔,所有 JavaScript 中要討論的新主意都會出現(xiàn)在ECMAScript Harmony 中。
ActionScript
ActionScript 是一個基于 ECMAScript 4 早期草案的編程語言糖声。Adobe 將其實現(xiàn)為 Flash 應(yīng)用程序套件的一部分斤彼,也是它支持的唯一的腳本語言分瘦。這就讓 Adobe 采用強(qiáng)硬的立場來支持 ECMAScript 4,甚至還將他們的引擎(Tamarin)開源發(fā)布了琉苇,以希望加快 ECMAScript 4 的采納嘲玫。Adobe 員工 Mike Chambers 爆光了一個在此事上的有趣看法:
ActionScript 3 沒有消失,我們基于最近的決定并扇,沒有從中刪除任何東西..我們會繼續(xù)跟蹤 ECMAScript 規(guī)范去团,但是正如我們一直所做的那樣,我們會創(chuàng)新穷蛹,盡可能推動 Web 向前發(fā)展(正如我們在過去已做過的那樣)- Mike Chamber 的博客
ActionScript 開發(fā)者期望 ActionScript 中的創(chuàng)新會驅(qū)動 ECMAScript 中的特性土陪。不幸的是這事從來沒有出現(xiàn)過,而且后來出現(xiàn)在 ECMAScript 2015 中的特性與 ActionScript 在很多方面不兼容肴熏。
有人看到這是微軟嘗試保持控制 ECMAScript 語言和實現(xiàn)的一種策略鬼雀。此時,唯一可行的 ECMAScript 4 引擎是 Tamarin蛙吏,所以此時占有 80% 瀏覽器市場份額的微軟可以繼續(xù)使用它自己的引擎(以及擴(kuò)展)源哩,而不用支付切換到競爭對手的替代品的費(fèi)用或者自身花時間實現(xiàn)一切。 其他人只是說微軟的異議僅僅是技術(shù)上的鸦做,比如來自 Yahoo 的某些人励烦。Microsoft 的引擎 JScript 此時與其它實現(xiàn)有很多差異。有人已經(jīng)看到這是保持秘密控制該語言的一種手段泼诱。
ActionScript 目前依然是 Flash 的開發(fā)語言崩侠,而 Flash 隨著 HTML5 的到來,逐漸從流行中淡出坷檩。
如果 ECMAScript 4 已經(jīng)被流行 JavaScript 引擎實現(xiàn)的話却音,ActionScript 依然與它最像:
package {
import flash.display.Sprite;
public class MyRectangle_v3 extends Sprite {
private var _outlineWeight:Number;
private var _color:uint;
private var _xLocation:int;
private var _yLocation:int;
private var _rectangleWidth:int;
private var _rectangleHeight:int;
public function MyRectangle_v3(outlineWeight:Number, color:uint,
xLocation:int, yLocation:int,
rectangleWidth:int, rectangleHeight:int) {
_outlineWeight = outlineWeight;
_color = color;
_xLocation = xLocation;
_yLocation = yLocation;
_rectangleWidth = rectangleWidth;
_rectangleHeight = rectangleHeight;
}
public function draw():void{
graphics.lineStyle(_outlineWeight);
graphics.beginFill(_color);
graphics.drawRect(_xLocation, _yLocation, _rectangleWidth, _rectangleHeight);
graphics.endFill();
}
}
}
E4X?什么是 E4X矢炼?
E4X 是一個公認(rèn)的 ECMAScript 擴(kuò)展的名稱系瓢。它在 ECMAScript 4 開發(fā)期間發(fā)布(2004年),所以就采用了綽號 E4X句灌。其實際名稱是 ECMAScript for XML夷陋,并被標(biāo)準(zhǔn)化為 ECMA-357。E4X 擴(kuò)充了 ECMAScript胰锌,以支持對 XML 內(nèi)容的原生處理和解析骗绕。在 E4X 中,XML 被當(dāng)作是一種原生數(shù)據(jù)類型资昧。它最初被主流 JavaScript 引擎(比如 SpiderMonkey)采納酬土,不過之后由于很少有人用而被拿掉。在 Firefox 版本 21 中被刪除格带。
除了其名稱中有數(shù)字 "4" 之外撤缴,E4X 與 ECMAScript 4 沒多大關(guān)系刹枉。
如下是一個使用 E4X 的示例:
var sales = <sales vendor="John">
<item type="peas" price="4" quantity="6"/>
<item type="carrot" price="3" quantity="10"/>
<item type="chips" price="5" quantity="3"/>
</sales>;
alert( sales.item.(@type == "carrot").@quantity );
alert( sales.@vendor );
for each( var price in sales..@price ) {
alert( price );
}
delete sales.item[0];
sales.item += <item type="oranges" price="4"/>;
sales.item.(@type == "oranges").@quantity = 4;
可以說,其它數(shù)據(jù)格式(比如 JSON)已經(jīng)在 JavaScript 社區(qū)中獲得了更廣泛的認(rèn)同屈呕,所以 E4X 出現(xiàn)和消失都沒惹啥亂子微宝。
ECMAScript 5:JavaScript 的重生
在 ECMAScript 4 的漫長斗爭之后,從 2008 年開始虎眨,社區(qū)就在注意力放在 ECMAScript 3.1 上蟋软。ECMAScript 4 被廢棄。在 2009 年嗽桩,ECMAScript 3.1 完成岳守,并且涉及的各方都簽字確認(rèn)了。而 ECMAScript 4 即使還沒有真正發(fā)布涤躲,也已經(jīng)被公認(rèn)為是 ECMAScript 的一個特定變種,所以委員會決定將 ECMAScript 3.1 重新命名為 ECMAScript 5贡未,以避免混淆种樱。
ECMAScript 5 成為了最受支持的 JavaScript 版本之一,也成為了很多轉(zhuǎn)譯器的編譯目標(biāo)俊卤。ECMAScript 5 被 Firefox 4 (2011)嫩挤、Chrome 19 (2012)、Safari 6 (2012)消恍、Opera 12.10 (2012) 和 Internet Explorer 10 (2012)完全支持岂昭。
- Getter/setters
- 數(shù)組和對象字面量中的尾隨逗號
- 保留關(guān)鍵字可以作為屬性名
- 新的 Object 方法(create、defineProperty狠怨、keys约啊、seal、freeze佣赖、getOwnPropertyNames 等等)
- 新的 Array 方法(isArray恰矩、indexOf、every憎蛤、 some外傅、map、filter俩檬、reduce 等等)
- String.prototype.trim 和屬性訪問
- 新的 Date 方法(toISOString萎胰、now、toJSON)
- 函數(shù) bind
- JSON
- 不可變的全局對象(undefined棚辽、NaN技竟、Infinity)
- 嚴(yán)格模式
- 其它次要的變更(parseInt 忽略前導(dǎo)零、拋出的函數(shù)有正確的 this 值屈藐,等等)
所有更新都不需要語法上的修改灵奖。那時 getter 和 setter 已經(jīng)被很多瀏覽器非正式地支持嚼沿。新的 Object 方法通過給程序員更多工具來確保強(qiáng)制某些不變性,來改進(jìn)“大型程序的編寫”(Object.seal瓷患、Object.freeze骡尽、Object.createProperty)。嚴(yán)格模式通過阻止很多常見的錯誤源擅编,在這一領(lǐng)域也成為一種強(qiáng)大的工具攀细。額外的 Array 方法改進(jìn)了某些函數(shù)式范式(map、reduce爱态、filter谭贪、every、some)锦担。另一個大變化是 JSON:一個受 JavaScript 啟發(fā)的數(shù)據(jù)格式俭识,現(xiàn)在通過 JSON.stringify 和 JSON.parse 原生支持了。其它變化基于實踐經(jīng)驗在幾個方面作出了小的改進(jìn)洞渔√酌模總而言之,ECMAScript 5 是適度的改進(jìn)磁椒,幫助 JavaScrpt 成為一種對于小腳本和較大的項目來說都更可用的語言堤瘤。依然有很多來自 ECMAScript 4 的好點(diǎn)子被廢棄,并且你會看到這些好點(diǎn)子又通過 ECMAScript Harmony 提案回歸浆熔。
2011 年本辐,ECMAScript 5 以 ECMAScript 5.1 的形式又來了一次迭代。這個版本澄清了標(biāo)準(zhǔn)中一些容易引起歧義之處医增,但是沒有提供任何新特性慎皱。所有的新特性定于在下一個 ECMAScript 的大發(fā)布中。
ECMAScript 6 (2015) 和 7 (2016): 一個通用的語言
ECMAScript Harmony 提案成為將來對 JavaScript 的改進(jìn)的中心叶骨。很多來自 ECMAScript 4 的理念被永遠(yuǎn)被取消了宝冕,但是其它的被用新的心態(tài)重新處理了。ECMAScript 6邓萨,后來被重新命名為 ECMAScript 2015地梨,被指定為帶來大變化。幾乎所有需要在語法上改變的更新都被放到這個版本中缔恳。不過宝剖,這次委員會達(dá)成了一致,ECMAScript 6 最終于 2015 年發(fā)布歉甚。很多瀏覽器廠家已經(jīng)開始著手實現(xiàn)它的特性万细,但是大的變動需要點(diǎn)時間。直到今天,并非所有瀏覽器都完全覆蓋 ECMAScript 2015(雖然它們已經(jīng)很接近)赖钞。
ECMAScript 2015 的發(fā)布導(dǎo)致轉(zhuǎn)譯器的使用大幅度增加腰素,比如 Babel 或 Traceur。甚至在它發(fā)布之前雪营,因為這些轉(zhuǎn)譯器跟蹤了技術(shù)委員會的進(jìn)展弓千,人們已經(jīng)體驗了很多 ECMAScript 2015 的好處。
一些 ECMAScript 4 的大特性在這個版本的 ECMAScript 中被實現(xiàn)献起。不過洋访,都是用不同的思維方式來實現(xiàn)的。例如谴餐,ECMAScript 2015 中的類只不過是在原型之上的語法糖姻政。這種思維模式減輕了新特性的過渡和開發(fā)。
在我們的JavaScript 2015 特性概述一文中岂嗓,我們對 ECMAScript 2015 的新特性做了一個全面的概述汁展。你也可以看看 ECMAScript 兼容性表,了解一下在實現(xiàn)方面我們現(xiàn)在的確切位置厌殉。
- Let(詞法上的)和 const(不可重新綁定的)綁定
- 箭頭函數(shù)(匿名函數(shù)的簡寫)以及詞法 this(包含作用域 this)
- 類(原型之上的語法糖)
- 對象字面量提升(計算鍵食绿、短方法定義等等)
- 模板字符串
- Promise
- Generator、iterable年枕、iterator 和 for..of
- 函數(shù)的默認(rèn)參數(shù)及剩余運(yùn)算符
- 擴(kuò)展語法
- 解構(gòu)
- 模塊語法
- 新集合(Set炫欺、Map乎完、WeakSet熏兄、WeakMap)
- 代理和反射
- Symbol 數(shù)據(jù)類型
- 類型化數(shù)組
- 內(nèi)置支持子類化
- 有保證的尾調(diào)用優(yōu)化
- 更簡單的 Unicode 支持
- 二進(jìn)制和八進(jìn)制字面量
類、let树姨、const摩桶、promise、generator帽揪、iterators硝清、模塊,等等转晰。這些特性都是為了把 JavaScript 帶給更多受眾芦拿,幫助開發(fā)大型應(yīng)用程序。
你也許會驚訝查邢,在 ECMAScript 4 失敗之時蔗崎,還有這么多特性能闖過標(biāo)準(zhǔn)化過程這一關(guān)。從這個層面上扰藕,必須得指出缓苛,ECMAScript 4 中很多最具侵入性的特性都沒有被重新考慮,比如邓深,命名空間未桥、可選類型笔刹;同時,其它的特性被以可以通過之前的異議的方式重新考慮了冬耿,比如舌菜,讓類成為原型之上的語法糖。ECMAScript 2015 依然是個苦差事淆党,花了約 6 年完成(并且需要更長時間完全實現(xiàn))酷师。不過,這樣艱巨的一個任務(wù)能被 ECMAScript 技術(shù)委員會完成染乌,也可以看作是好事要來臨的一個好跡象山孔。
2016 年,一個 ECMAScript 的小修訂版發(fā)布了荷憋。這個小修訂版是 TC-39 實施的新發(fā)布過程的結(jié)果台颠。所有新提案必須經(jīng)過四個階段的過程。每個達(dá)到第四個階段的提案有很大機(jī)會會被包含在下一個版本的 ECMAScript 中(不過委員會依然可以選擇推遲將其列入議程)勒庄。這樣串前,提案就幾乎可以獨(dú)立開發(fā)(不過與其它提案的交互必須在考慮之列)。提案不會中斷 ECMAScript 的開發(fā)实蔽。如果一個提案已經(jīng)準(zhǔn)備列入荡碾,并且足夠的提案已經(jīng)達(dá)到第四階段,那么就可以發(fā)布一個 ECMAScript 新版本局装。
2016 年發(fā)布的版本是一個相當(dāng)小的版本坛吁。它包括:
- 取冪運(yùn)算符(**)
- Array.prototype.includes
- 一些小的更正(generator 不能與 new 一起用等等)
- stage-x:
- Stage 0 - 稻草人: 只是一個想法,可能是 babel 插件铐尚。
- Stage 1 - 提案: 初步嘗試拨脉。
- Stage 2 - 初稿: 完成初步規(guī)范。
- Stage 3 - 候選: 完成規(guī)范和瀏覽器初步實現(xiàn)宣增。
- Stage 4 - 完成: 將被添加到下一年度發(fā)布玫膀。
不過,在 2016 年爹脾,某些有趣的提案已經(jīng)達(dá)到第四階段帖旨,所以 ECMAScript 的未來是什么呢?
未來與超越:ECMAScipt 2017 及以后
也許目前進(jìn)行中的最重要的第四階段提案是 async/await灵妨。Async/await 是對 JavaScript 的一種語法擴(kuò)展解阅,可以讓處理 promise 變得更爽。例如闷串,對于如下 ECMAScript 2015 代碼:
function apiDoSomethingMoreComplex(withThis) {
const urlA = '...';
const urlB = '...';
httpLib.request(urlA, withThis).then(result => {
const parsed = parseResult(result);
return new Promise((resolve, reject) => {
database.update(updateStatement, parsed).then(() => {
resolve(parsed);
}, error => {
reject(error);
});
});
}).then(result => {
return httpLib.request(urlB, result);
}).then(result => {
return worker.processData(result);
}).then(result => {
logger.info(`apiDoSomethingMoreComplex success (${result})`);
}, error => {
logger.error(error);
});
}
把它與如下的 async/await 代碼比較:
async function apiDoSomethingMoreComplex(withThis) {
const urlA = '...';
const urlB = '...';
try {
let result = await httpLib.request(urlA, withThis);
const parsed = parseResult(result);
await database.update(updateStatement, parsed);
result = await httpLib.request(urlB, parsed);
result = await worker.processData(result);
logger.info(`apiDoSomethingMoreComplex success (${result})`);
} catch(e) {
logger.error(e);
}
}
其它第四階段的提案在范圍上都是次要的:
- Object.values 和 Object.entries
- 字符串補(bǔ)白
- Object.getOwnPropertyDescriptors
- 函數(shù)參數(shù)允許尾隨逗號
這些提案都是定于在 2017 年發(fā)布瓮钥,不過委員會可能會選擇自行決定推遲。不過,僅是有async/await 這一點(diǎn)就是一件讓人激動的變動碉熄。
但是未來并非止步于此桨武!我們可以看看其它的一些提案,了解一下更遠(yuǎn)的未來會出現(xiàn)什么锈津。一些有趣的提案是:
- SIMD API
- 異步迭代(async/await + 迭代)
- Generator 箭頭函數(shù)
- 64 位 整型操作
- Realm(狀態(tài)分離/隔離)
- 共享內(nèi)存和原子
JavaScript 正越來越像一門通用的語言呀酸。不過,還有一件對 JavaScript 的未來會產(chǎn)生重大影響的大事情琼梆。
WebAssembly
如果你還沒聽說過 WebAssembly性誉,就應(yīng)該讀讀這篇文章。自 ECMAScript 5 發(fā)布以來茎杂,引發(fā)的庫错览、框架和一般開發(fā)的激增,已經(jīng)讓 JavaScript 變成了對其它語言的一個有興趣的目標(biāo)煌往。對于大的代碼庫倾哺,可互操作性是關(guān)鍵。比如說游戲刽脖。游戲開發(fā)的通用語言依然是 C++羞海,并且它對很多架構(gòu)來說都是可移植的。將一個 Windows 游戲或者控制臺游戲移植到瀏覽器上被看作是一件不可能實現(xiàn)的任務(wù)曲管。不過却邓,當(dāng)前 JIT JavaScript 虛擬機(jī)不可思議的性能讓這成為可能。于是院水,像 Emscripten 這種 LLVM-to-JavaScript 編譯器應(yīng)運(yùn)而生腊徙。
Mozilla 看到了這點(diǎn),并開始著手研究讓 JavaScript 變成編譯器的合適目標(biāo)衙耕。Asm.js 誕生了昧穿。Asm.js 是 JavaScript 的一個嚴(yán)格子集勺远,用來作為編譯器的目標(biāo)橙喘。JavaScript 虛擬機(jī)可以被優(yōu)化為識別這個子集,并且生成比目前可能在普通 JavaScript 代碼中更好的代碼胶逢。瀏覽器慢慢變成了一個編譯應(yīng)用的全新目標(biāo)厅瞎,而 JavaScript 在其中心。
不過初坠,有些限制是 Asm.js 也不能解決了和簸。畢竟這與 JavaScript 的用途無關(guān),所以必須要對 JavaScript 作出改變碟刺。要讓 web 成為其它語言的合適目標(biāo)锁保,就需要點(diǎn)不同的東西,而這正是 WebAssembly 所有的。WebAssembly 是用于 Web 的字節(jié)碼爽柒。任何帶有合適編譯器的程序吴菠,都可以被編譯為 WebAssembly,然后運(yùn)行在合適的虛擬機(jī)上(JavaScript 虛擬機(jī)可以提供所需的語義)浩村。實際上做葵,首版 WebAssembly 就以與 Asm.js 規(guī)范一對一兼容為目標(biāo)。WebAssembly 不僅帶來了加載時間更快的承諾(解析字節(jié)碼比解析文本更快)心墅,還帶來了 Asm.js 中目前還不能用的可能優(yōu)化酿矢。想像一下,JavaScript 和你已有的代碼之間能完美互用的 Web怎燥。
乍一看瘫筐,這好像是危及到 JavaScript 的發(fā)展,然而事實恰好相反铐姚。通過讓其它語言和框架更容易與 JavaScript 互用严肪,JavaScript 就可以繼續(xù)發(fā)展為一門通用的語言。而WebAssembly 是為此必需的工具谦屑。
目前驳糯,Chrome、Firefox 和 Microsot Edge 的開發(fā)版支持 WebAsembly 規(guī)范草案氢橙,并且能夠運(yùn)行演示應(yīng)用程序酝枢。
總結(jié)
JavaScript 的歷史漫長而崎嶇。它先被提議為用于 Web 的 Scheme悍手,然后早早就被類 Java 的語法束縛住了帘睦。它的第一個原型在幾周之內(nèi)就被開發(fā)出來了。受市場之害坦康,它在兩年之內(nèi)變了三個名字竣付。然后被標(biāo)準(zhǔn)化了,同時得到一個聽起來像皮膚病的名字滞欠。在三次成功的發(fā)布后古胆,第四版陷入開發(fā)地獄約八年。開發(fā)方向一變再變筛璧,莫衷一是逸绎。然后,純通過一個特性(AJAX)的成功夭谤,社區(qū)又重歸行動一致棺牧,恢復(fù)了開發(fā)。第 4 版被廢棄朗儒,一個次要版本颊乘,即人人皆知的 第 3.1 版本参淹,被重命名為 第 5 版。第 6 版又在開發(fā)上花了很多年乏悄,不過這次委員會成功了承二,雖然又決定改名,但是這次是改為 2015纲爸。這個修訂版很大亥鸠,花了很多時間實現(xiàn)。但是最終识啦,給 JavaScript 帶來了新風(fēng)负蚊。社區(qū)像以前一樣活躍。Node.js颓哮、V8 和其它項目已經(jīng)把 JavaScript 帶到了一個前所未有的地步家妆。Asm.js、WebAssembly 正進(jìn)一步改進(jìn)它冕茅。并且不同階段活躍的提案都讓 JavaScript 的未來像以前一樣光明伤极。這是一條漫長的路,充滿崎嶇姨伤,而 JavaScript 依然始終是最成功的語言之一哨坪。這本身就是一種證明。永遠(yuǎn)把賭注押在 JavaScript 上乍楚。