一、什么是JavaScript?
JavaScript 是一種輕量級(jí)的腳本語(yǔ)言。所謂“腳本語(yǔ)言”,指的是它不具備開發(fā)操作系統(tǒng)的能力,而是只用來(lái)編寫控制其他大型應(yīng)用程序的“腳本”。
JavaScript 是一種嵌入式(embedded)語(yǔ)言。它本身提供的核心語(yǔ)法不算很多,只能用來(lái)做一些數(shù)學(xué)和邏輯運(yùn)算。JavaScript 本身不提供任何與 I/O(輸入/輸出)相關(guān)的 API,都要靠宿主環(huán)境(host)提供,所以 JavaScript 只合適嵌入更大型的應(yīng)用程序環(huán)境,去調(diào)用宿主環(huán)境提供的底層 API。
目前,已經(jīng)嵌入 JavaScript 的宿主環(huán)境有多種,最常見(jiàn)的環(huán)境就是瀏覽器,另外還有服務(wù)器環(huán)境,也就是 Node 項(xiàng)目。
從語(yǔ)法角度看,JavaScript語(yǔ)言是一種“對(duì)象模型”語(yǔ)言。各種宿主環(huán)境通過(guò)這個(gè)模型,描述自己的功能和操作接口,從而通過(guò) JavaScript 控制這些功能。但是,JavaScript 并不是純粹的“面向?qū)ο笳Z(yǔ)言”,還支持其他編程范式(比如函數(shù)式編程)。這導(dǎo)致幾乎任何一個(gè)問(wèn)題,JavaScript 都有多種解決方法。閱讀本書的過(guò)程中,你會(huì)震驚地發(fā)現(xiàn),JavaScript 語(yǔ)法是多么的靈活。
JavaScript 的核心語(yǔ)法部分相當(dāng)精簡(jiǎn),只包括兩個(gè)部分:基本的語(yǔ)法構(gòu)造(比如操作符、控制結(jié)構(gòu)、語(yǔ)句)和標(biāo)準(zhǔn)庫(kù)(就是一系列具有各種功能的對(duì)象比如Array、Date、Math等)。除此之外,各種宿主環(huán)境提供額外的 API(即只能在該環(huán)境使用的接口),以便 JavaScript 調(diào)用。以瀏覽器為例,它提供的額外 API 可以分成三大類。
瀏覽器控制類:操作瀏覽器
DOM 類:操作網(wǎng)頁(yè)的各種元素
Web 類:實(shí)現(xiàn)互聯(lián)網(wǎng)的各種功能
如果宿主環(huán)境是服務(wù)器,則會(huì)提供各種操作系統(tǒng)的 API,比如文件操作 API、網(wǎng)絡(luò)通信 API等等。這些你都可以在 Node 環(huán)境中找到。
二、JavaScript的誕生
JavaScript因?yàn)榛ヂ?lián)網(wǎng)而生,緊隨著瀏覽器的出現(xiàn)而問(wèn)世。回顧它的歷史,就要從瀏覽器的歷史講起。
1990年底,歐洲核能研究組織(CERN)科學(xué)家Tim Berners-Lee,在全世界最大的電腦網(wǎng)絡(luò)——互聯(lián)網(wǎng)的基礎(chǔ)上,發(fā)明了萬(wàn)維網(wǎng)(World Wide Web),從此可以在網(wǎng)上瀏覽網(wǎng)頁(yè)文件。最早的網(wǎng)頁(yè)只能在操作系統(tǒng)的終端里瀏覽,也就是說(shuō)只能使用命令行操作,網(wǎng)頁(yè)都是在字符窗口中顯示,這當(dāng)然非常不方便。
1992年底,美國(guó)國(guó)家超級(jí)電腦應(yīng)用中心(NCSA)開始開發(fā)一個(gè)獨(dú)立的瀏覽器,叫做Mosaic。這是人類歷史上第一個(gè)瀏覽器,從此網(wǎng)頁(yè)可以在圖形界面的窗口瀏覽。
1994年10月,NCSA的一個(gè)主要程序員Marc Andreessen聯(lián)合風(fēng)險(xiǎn)投資家Jim Clark,成立了Mosaic通信公司(Mosaic Communications),不久后改名為Netscape。這家公司的方向,就是在Mosaic的基礎(chǔ)上,開發(fā)面向普通用戶的新一代的瀏覽器Netscape Navigator。
1994年12月,Navigator發(fā)布了1.0版,市場(chǎng)份額一舉超過(guò)90%。
Netscape公司很快發(fā)現(xiàn),Navigator瀏覽器需要一種可以嵌入網(wǎng)頁(yè)的腳本語(yǔ)言,用來(lái)控制瀏覽器行為。當(dāng)時(shí),網(wǎng)速很慢而且上網(wǎng)費(fèi)很貴,有些操作不宜在服務(wù)器端完成。比如,如果用戶忘記填寫“用戶名”,就點(diǎn)了“發(fā)送”按鈕,到服務(wù)器再發(fā)現(xiàn)這一點(diǎn)就有點(diǎn)太晚了,最好能在用戶發(fā)出數(shù)據(jù)之前,就告訴用戶“請(qǐng)?zhí)顚懹脩裘薄_@就需要在網(wǎng)頁(yè)中嵌入小程序,讓瀏覽器檢查每一欄是否都填寫了。
管理層對(duì)這種瀏覽器腳本語(yǔ)言的設(shè)想是:功能不需要太強(qiáng),語(yǔ)法較為簡(jiǎn)單,容易學(xué)習(xí)和部署。那一年,正逢Sun公司的Java語(yǔ)言問(wèn)世,市場(chǎng)推廣活動(dòng)非常成功。Netscape公司決定與Sun公司合作,瀏覽器支持嵌入Java小程序(后來(lái)稱為Java applet)。但是,瀏覽器腳本語(yǔ)言是否就選用Java,則存在爭(zhēng)論。后來(lái),還是決定不使用Java,因?yàn)榫W(wǎng)頁(yè)小程序不需要Java這么“重”的語(yǔ)法。但是,同時(shí)也決定腳本語(yǔ)言的語(yǔ)法要接近Java,并且可以支持Java程序。這些設(shè)想直接排除了使用現(xiàn)存語(yǔ)言,比如Perl、Python和TCL。
1995年,Netscape公司雇傭了程序員Brendan Eich開發(fā)這種網(wǎng)頁(yè)腳本語(yǔ)言。Brendan Eich有很強(qiáng)的函數(shù)式編程背景,希望以Scheme語(yǔ)言(函數(shù)式語(yǔ)言鼻祖LISP語(yǔ)言的一種方言)為藍(lán)本,實(shí)現(xiàn)這種新語(yǔ)言。
1995年5月,Brendan Eich只用了10天,就設(shè)計(jì)完成了這種語(yǔ)言的第一版。它是一個(gè)大雜燴,語(yǔ)法有多個(gè)來(lái)源:
基本語(yǔ)法:借鑒C語(yǔ)言和Java語(yǔ)言。
數(shù)據(jù)結(jié)構(gòu):借鑒Java語(yǔ)言,包括將值分成原始值和對(duì)象兩大類。
函數(shù)的用法:借鑒Scheme語(yǔ)言和Awk語(yǔ)言,將函數(shù)當(dāng)作第一等公民,并引入閉包。
原型繼承模型:借鑒Self語(yǔ)言(Smalltalk的一種變種)。
正則表達(dá)式:借鑒Perl語(yǔ)言。
字符串和數(shù)組處理:借鑒Python語(yǔ)言。
為了保持簡(jiǎn)單,這種腳本語(yǔ)言缺少一些關(guān)鍵的功能,比如塊級(jí)作用域、模塊、子類型(subtyping)等等,但是可以利用現(xiàn)有功能找出解決辦法。這種功能的不足,直接導(dǎo)致了后來(lái)JavaScript的一個(gè)顯著特點(diǎn):對(duì)于其他語(yǔ)言,你需要學(xué)習(xí)語(yǔ)言的各種功能,而對(duì)于JavaScript,你常常需要學(xué)習(xí)各種解決問(wèn)題的模式。而且由于來(lái)源多樣,從一開始就注定,JavaScript的編程風(fēng)格是函數(shù)式編程和面向?qū)ο缶幊痰囊环N混合體。
Netscape公司的這種瀏覽器腳本語(yǔ)言,最初名字叫做Mocha,1995年9月改為L(zhǎng)iveScript。12月,Netscape公司與Sun公司(Java語(yǔ)言的發(fā)明者和所有者)達(dá)成協(xié)議,后者允許將這種語(yǔ)言叫做JavaScript。這樣一來(lái),Netscape公司可以借助Java語(yǔ)言的聲勢(shì),而Sun公司則將自己的影響力擴(kuò)展到了瀏覽器。
之所以起這個(gè)名字,并不是因?yàn)镴avaScript本身與Java語(yǔ)言有多么深的關(guān)系(事實(shí)上,兩者關(guān)系并不深),而是因?yàn)镹etscape公司已經(jīng)決定,使用Java語(yǔ)言開發(fā)網(wǎng)絡(luò)應(yīng)用程序,JavaScript可以像膠水一樣,將各個(gè)部分連接起來(lái)。當(dāng)然,后來(lái)的歷史是Java語(yǔ)言的瀏覽器插件失敗了,JavaScript反而發(fā)揚(yáng)光大。
1995年12月4日,Netscape公司與Sun公司聯(lián)合發(fā)布了JavaScript語(yǔ)言。
1996年3月,Navigator 2.0瀏覽器正式內(nèi)置了JavaScript腳本語(yǔ)言。
三、JavaScript的版本
1997年7月,ECMAScript 1.0發(fā)布。
1998年6月,ECMAScript 2.0版發(fā)布。
1999年12月,ECMAScript 3.0版發(fā)布,成為JavaScript的通行標(biāo)準(zhǔn),得到了廣泛支持。
2007年10月,ECMAScript 4.0版草案發(fā)布,對(duì)3.0版做了大幅升級(jí),預(yù)計(jì)次年8月發(fā)布正式版本。草案發(fā)布后,由于4.0版的目標(biāo)過(guò)于激進(jìn),各方對(duì)于是否通過(guò)這個(gè)標(biāo)準(zhǔn),發(fā)生了嚴(yán)重分歧。以Yahoo、Microsoft、Google為首的大公司,反對(duì)JavaScript的大幅升級(jí),主張小幅改動(dòng);以JavaScript創(chuàng)造者Brendan Eich為首的Mozilla公司,則堅(jiān)持當(dāng)前的草案。
2008年7月,由于對(duì)于下一個(gè)版本應(yīng)該包括哪些功能,各方分歧太大,爭(zhēng)論過(guò)于激進(jìn),ECMA開會(huì)決定,中止ECMAScript 4.0的開發(fā)(即廢除了這個(gè)版本),將其中涉及現(xiàn)有功能改善的一小部分,發(fā)布為ECMAScript 3.1,而將其他激進(jìn)的設(shè)想擴(kuò)大范圍,放入以后的版本,由于會(huì)議的氣氛,該版本的項(xiàng)目代號(hào)起名為Harmony(和諧)。會(huì)后不久,ECMAScript 3.1就改名為ECMAScript 5。
2009年12月,ECMAScript 5.0版正式發(fā)布。Harmony項(xiàng)目則一分為二,一些較為可行的設(shè)想定名為JavaScript.next繼續(xù)開發(fā),后來(lái)演變成ECMAScript 6;一些不是很成熟的設(shè)想,則被視為JavaScript.next.next,在更遠(yuǎn)的將來(lái)再考慮推出。TC39的總體考慮是,ECMAScript 5與ECMAScript 3基本保持兼容,較大的語(yǔ)法修正和新功能加入,將由JavaScript.next完成。當(dāng)時(shí),JavaScript.next指的是ECMAScript 6。第六版發(fā)布以后,將指ECMAScript 7。TC39預(yù)計(jì),ECMAScript 5會(huì)在2013年的年中成為JavaScript開發(fā)的主流標(biāo)準(zhǔn),并在此后五年中一直保持這個(gè)位置。
2011年6月,ECMAscript 5.1版發(fā)布,并且成為ISO國(guó)際標(biāo)準(zhǔn)(ISO/IEC 16262:2011)。到了2012年底,所有主要瀏覽器都支持ECMAScript 5.1版的全部功能。
2013年3月,ECMAScript 6草案凍結(jié),不再添加新功能。新的功能設(shè)想將被放到ECMAScript 7。
2013年12月,ECMAScript 6草案發(fā)布。然后是12個(gè)月的討論期,聽取各方反饋。
2015年6月,ECMAScript 6正式發(fā)布,并且更名為“ECMAScript 2015”。這是因?yàn)門C39委員會(huì)計(jì)劃,以后每年發(fā)布一個(gè)ECMAScirpt的版本,下一個(gè)版本在2016年發(fā)布,稱為“ECMAScript 2016”。
除了ECMAScript的版本,很長(zhǎng)一段時(shí)間中,Netscape公司(以及繼承它的Mozilla基金會(huì))在內(nèi)部依然使用自己的版本號(hào)。這導(dǎo)致了JavaScript有自己不同于ECMAScript的版本號(hào)。1996年3月,Navigator 2.0內(nèi)置了JavaScript 1.0。JavaScript 1.1版對(duì)應(yīng)ECMAScript 1.0,但是直到JavaScript 1.4版才完全兼容ECMAScript 1.0。JavaScript 1.5版完全兼容ECMAScript 3.0。目前的JavaScript 1.8版完全兼容ECMAScript 5。
來(lái)自《JavaScript 標(biāo)準(zhǔn)參考教程(alpha)》,by 阮一峰