JavaScript

本页使用了标题或全文手工转换,现处于澳门繁体模式
求聞百科,共筆求聞
JavaScript
編程範型事件驅動函數式指令式
設計者創造者布蘭登·艾克ECMAScript規範的其他關鍵貢獻者
釋出時間1995年12月4日,​28年前​(1995-12-04[1]
穩定版本
ECMAScript 2019[2]
(2019年6月,​4年前​(2019-06
預覽版本
ECMAScript 2020
型態系統動態型別鴨子型別
副檔名
主要實作產品
V8JavaScriptCoreSpiderMonkeyChakra
受啟發於
AWKCHyperTalkJava[4]LuaPerlPythonSchemeSelf
施影響於
ActionScriptAtScriptCoffeeScriptDartJScript .NETLiveScriptObjective-JOpaQMLRakuTypeScript
JavaScript
副檔名.js
網路媒體型式application/javascript
text/javascript (obsolete)[5]
統一類型標識com.netscape.javascript-source[6]
格式類型程式语言

JavaScript(通常縮寫為JS)是一種進階的、直译程式語言[7]。JavaScript是一門基於原型頭等函數的語言[8],是一門多範式的語言,它支援物件導向程式設計,指令式編程,以及函式語言程式設計。它提供語法來操控文字、陣列、日期以及正則表達式等,不支援I/O,比如網絡、儲存和圖形等,但這些都可以由它的宿主環境提供支援。它已經由ECMA(歐洲電腦製造商協會)通过ECMAScript实作語言的標準化[7]。它被世界上的絕大多數網站所使用,也被世界主流瀏覽器ChromeIEFirefoxSafariOpera)支援。

JavaScript與Java在名字或語法上都有很多相似性,但這兩門程式語言從設計之初就有很大的不同,JavaScript的語言設計主要受到了Self(一種原型程式設計語言)和Scheme(一門函式語言程式設計語言)的影響[8]。在語法結構上它又與C語言有很多相似(例如if條件陳述式、switch陳述式、while迴圈、do-while迴圈等)[9]

在客戶端,JavaScript在傳統意義上被实作為一種解釋語言,但在最近,它已經可以被即時編譯(JIT)執行。隨着最新的HTML5CSS3語言標準的推行它還可用於遊戲、桌面和流動應用程式的開發和在伺服器端網絡環境執行,如Node.js

歷史

肇始於網景

1993年,美國國家超級電腦應用中心(NCSA)發表了NCSA Mosaic瀏覽器,這是最早流行的圖形介面網頁瀏覽器,它在全球資訊網的普及上發揮了重要作用[10]。1994年,Mosaic的主要開發人員隨即創立了Netscape公司,並僱用了許多原來的NCSA Mosaic開發者用來開發Netscape Navigator,該公司的目標是取代NCSA Mosaic成為世界第一的網頁瀏覽器。在四個月內,已經佔據了四分之三的瀏覽器市場,並成為1990年代網際網路的主要瀏覽器[11]。網景預見到網路需要變得更動態。公司的創始人馬克·安德森認為HTML需要一種膠水語言,讓網頁設計師和兼職程式設計師可以很容易地使用它來組裝圖片和外掛程式之類的元件,且程式碼可以直接編寫在網頁標記中。

1995年,網景招募了布蘭登·艾克,目標是把Scheme語言嵌入到Netscape Navigator瀏覽器當中[12]。但更早之前,網景已經跟昇陽合作在Netscape Navigator中支援Java,這時網景內部產生激烈的爭論[13]。後來網景決定發明一種與Java搭配使用的輔助程式语言並且語法上有些類似[14],這個決策導致排除了採用現有的語言,例如PerlPythonTcl或Scheme。為了在其他競爭提案中捍衛JavaScript這個想法,公司需要有一個可以運作的原型。艾克在1995年5月僅花了十天時間就把原型設計出來了。

最初命名為Mocha,1995年9月在Netscape Navigator 2.0的Beta版中改名為LiveScript,同年12月,Netscape Navigator 2.0 Beta 3中部署時被重新命名為JavaScript[1][15],當時網景公司與太阳电脑公司組成的開發聯盟為了讓這門語言搭上Java這個程式語言「熱詞」,因此將其臨時改名為JavaScript,日後這成為大眾對這門語言有諸多誤解的原因之一。

微軟採納

微軟公司於1995年首次推出Internet Explorer,從而引發了與Netscape的瀏覽器大戰。微軟對Netscape Navigator直譯器進行了逆向工程,建立了JScript,以與處於市場領導地位的網景產品同台競爭。JScript也是一種JavaScript实作,這兩個JavaScript語言版本在瀏覽器端共存意味着語言標準化的缺失,發展初期,JavaScript的標準並未確定,同期有網景的JavaScript,微軟的JScript雙峰並峙。除此之外,微軟也在網頁技術上加入了不少專屬物件,使不少網頁使用非微軟平台及瀏覽器無法正常顯示[16][17],導致在瀏覽器大戰期間網頁設計者通常會把「用Netscape可達到最佳效果」或「用IE可達到最佳效果」的標誌放在首頁[16][18]

標準化

1996年11月,網景正式向ECMA(歐洲電腦製造商協會)提交語言標準。1997年6月,ECMA以JavaScript語言為基礎制定了ECMAScript標準規範ECMA-262。JavaScript成為了ECMAScript最著名的实作之一[19]。除此之外,ActionScriptJScript也都是ECMAScript規範的实作語言。儘管JavaScript作為給非程式人員的程式语言,而非作為給程式人員的程式语言來推廣和宣傳,但是JavaScript具有非常豐富的特性。

概論

一般來說,完整的JavaScript包括以下幾個部分:

  • ECMAScript,描述了該語言的語法和基本物件
  • 文件物件模型(DOM),描述處理網頁內容的方法和介面
  • 瀏覽器物件模型(BOM),描述與瀏覽器進行互動的方法和介面

JavaScript的基本特點如下:

  • 是一種解釋性程式语言(代碼不進行預編譯)。
  • 主要用來向HTML頁面添加互動行為
  • 可以直接嵌入HTML頁面,但寫成單獨的js檔案有利於結構和行為的分離。

JavaScript常用來完成以下任務:

  • 嵌入動態文字於HTML頁面
  • 對瀏覽器事件作出響應
  • 讀寫HTML元素
  • 在數據被提交到伺服器之前驗證數據
  • 檢測訪客的瀏覽器資訊
  • 控制cookie,包括建立和修改等

特性

不同於伺服器端程式语言,例如PHPASP,JavaScript主要被作為客戶端程式语言在用戶的瀏覽器上執行,不需要伺服器的支援。所以在早期程式設計師比較青睞於JavaScript以減少對伺服器的負擔,而與此同時也帶來另一個問題:安全性。而隨着伺服器變得強大,現在的程式設計師更喜歡執行於伺服器端的指令碼以保證安全,但JavaScript仍然以其跨平台、容易上手等優勢大行其道。同時,有些特殊功能(如AJAX)必須依賴JavaScript在客戶端進行支援。隨着引擎如V8和框架如Node.js的發展,及其事件驅動非同步IO等特性,JavaScript逐漸被用來編寫伺服器端程式。且在近幾年中,Node.js的出世,讓JavaScript也具有了一定的伺服器功能。

以下是ECMAScript通常实作所共有的特性。

指令式與結構化

JavaScript從支援許多C語言的結構化編程語法(例如if條件陳述式、while迴圈、switch陳述式、do-while迴圈等)。但作用域是一個例外:JavaScript在過去只支援使用var關鍵字來定義變數的函數作用域。ECMAScript 2015加入了let關鍵字來支援塊級作用域[20]。意味着JavaScript現在既支援函數作用域又支援塊級作用域。和C語言一樣,JavaScript中的表達式和陳述式是不同的。有一點格式上的不同,JavaScript支援自動在陳述式末添加分號,因此允許忽略陳述式末尾的分號。[21]

弱型別

Javascript是弱型別的,這意味着變數可以被隱式地轉換為另一個類型。[22]

  • 二元運算子+會把兩個運算元轉換為字串,除非兩個運算元都為數字類型。[23]這是因為+也表示字串連接操作。
  • 二元運算子-會把兩個運算元轉換為數字類型。[24]
  • 一元運算子,包括+-,都會把運算元轉換為數字。

下列為變數轉換為字串的例子:

  • 字串類型不變。
  • 數字會轉換為其字串表示。
  • 陣列的元素會轉換為字串,然後連接成通过逗號,分隔的長字串。
  • 其它物件會轉換為[object Object],其中Object中該物件的建構函式名。[25]

類型的隱藏轉換,是JavaScript受到批評的原因之一,因為其增加了規則的複雜度與發生錯誤的可能性。[26]

JavaScript中詭異的隱式轉換[27][28]:
左運算元 運算子 右運算元 結果
[](空陣列) + [](空陣列) ""(空字串)
[](空陣列) + {}(空物件) "[object Object]"(字串)
false(布林值) + [](空字串) "false"(字串)
"123"(字串) + 1(數字) "1231"(字串)
"123"(字串) - 1(數字) 122 (數字)

動態化

類型

JavaScript是動態型別的,正如大部分程式语言,其類型與值而不是與變數關聯。例如變數可以為數值,隨後又可被賦值為字串。JavaScript提供了包括鴨子型別在內的方法來檢測變數類型。

執行時估值

Javascript提供eval()函數,可以在執行時直接執行Javascript陳述式。[29]

基於原型的物件導向

在JavaScript中,物件是關聯陣列,通过原型(prototype,見下)進行擴充。每一個字串鍵值提供物件的一個屬性的名稱。可以通过兩種效果相同的方式進行存取:使用點號(obj.x)或使用方括號(obj['x'])。屬性可以在執行時添加、重定義或刪除。一個物件大多數屬性(包括來自原型繼承鏈的屬性)都可以通过 for...in迴圈存取。[30]

原型

JavaScript使用原型,而許多其它物件導向語言使用類用於实作繼承。有了原型,使得在JavaScript中模擬類別為基的物件導向特徵變成可能。[31]

函數作為物件構造器

函數在JavaScript中兼作為物件建構函式。在函數呼叫前加上new會建立一個原型的實例,並繼承來自建構函式的屬性和方法(包括來自Object原型)。[32]ECMAScript 5提供Object.create方法,可以顯式地建立實例還不是自動從Object繼承。[33]建構函式的prototype屬性決定了用於新物件的內部原型。可以通过修改建構函式的原型的方法來為物件添加新的方法。也可以修改JavaScript的內部物件的原型,如ArrayObject。儘管可以這麼做,但對Object原型進行修改並不是一個好的做法。因為大多數JavaScript物件都會從Object繼承,且不會希望其原型做了修改。[34]

函數作為方法

與大多數而向物件的語言不同,在JavaScript中函數定義與方法定義沒有明顯的區別。唯一的區別在於呼叫時:當函數被作為方法呼叫時,函數的this會指向呼叫此函數的物件。[35]

傳統的類別定義與使用格式

ECMAScript ES6加入了對classextends關鍵字的支援,使得類的定義與繼承行為更加類似於其它物件導向語言,同時也更加容易使用。[36][37]

函數式

在JavaScript中,函數是一等的,函數也被認為是物件。因此,函數也可以有屬性與方法,例如call()bind等。[38]巢狀函數指定義於其它函數內部的函數,在外部函數被呼叫時,巢狀函數會被建立。另外,巢狀函數是一個閉包,在外部函數的作用域(包括常數,局部變數和參數)都成為內部函數狀態的一部分,甚至在外部函數執行完畢後,內部函數的狀態依然保留。[39]JavaScript同時也支援匿名函數[40]

其它

執行時環境

JavaScript通常依賴於執行時環境(例如瀏覽器)來提供物件和方法,指令碼可以通过這些物件和方法與環境(例如網頁DOM)進行互動。它還依賴於執行時環境來提供包含/匯入指令碼(例如HTML<script>元素)的功能。這本身不是語言功能,但是在大多數JavaScript实作中很常見。

非同步

JavaScript一般來說是單線程的。[41]為了並行地處理事件,JavaScript程式輸入/輸出是使用事件回呼函數執行的。例如,這意味着JavaScript可以在等待數據庫查詢返回資訊時處理滑鼠單擊。ECMAScript ES6引入了Promise用於優雅地處理非同步事件,其可以使得傳統的基於回呼的非同步代碼更加清晰與簡單。[42][43]

變長參數

JavaScript中函數的參數長度是可變的,在函數內部可以通过arguments物件存取這些參數。[44]

編程

JavaScript是一種程式语言,其原始碼在發往客戶端執行之前不需經過編譯,而是將文字格式的字元代碼傳送給瀏覽器由瀏覽器解釋執行。直譯語言的弱點是安全性較差,而且在JavaScript中,如果一條執行不了,那麼下面的語言也無法執行。而其解決辦法就是於使用例外處理try {} catch () {}

console.log("a");  //这是正确的
console.log("b");  //这是正确的
console.logg("c"); //这是錯误的,并且到这里会停下来
console.log("d");  //这是正确的
console.log("e");  //这是正确的

/* 解決办法 */
try { console.log("a"); } catch (e) {}  //这是正确的
try { console.log("b"); } catch (e) {}  //这是正确的
try { console.logg("c"); } catch (e) {} //这是錯误的,但是到这里不会停下来,而是跳过
try { console.log("d"); } catch (e) {}  //这是正确的
try { console.log("e"); } catch (e) {}  //这是正确的

JavaScript被歸類為直譯語言,因為目前主流的引擎都是每次執行時載入程式碼並解譯。V8是將所有程式碼解譯後再開始執行,其他引擎則是逐行解譯(SpiderMonkey會將解譯過的指令暫存,以提高效能,稱為即時編譯),但由於V8的核心部份多數用JavaScript撰寫(而SpiderMonkey是用C++),因此在不同的測試上,兩者效能互有優劣。

與其相對應的是編譯語言,例如C語言,以編譯語言編寫的程式在執行之前,必須經過編譯,將程式碼編譯為機器碼,再加以執行。

範例

以下是一個簡單的JavaScript Hello World

<!DOCTYPE HTML>
<html>
    <head>
    <title>简单的JavaScript Hello World</title>
        <script>
            document.write("Hello, world!");   // 于浏览器视窗内直接显示
            alert("Hello, world!");            // 开启对话视窗显示
            console.log("Hello, world!");      // 于console里显示,需要先开启开发工具控制台
        </script>
    </head>
    <body>
    HTML内容……
    </body>
</html>

或是在瀏覽器网址列中使用javascript:,以互動方式表示:

javascript:alert("Hello world!");

版本

JavaScript最初開發於1996年,被使用於Netscape Navigator網頁瀏覽器。同年微軟在Internet Explorer發佈了一個实作。由於商標問題,這項实作被命名為JScript。1997年,JavaScript已經被網景公司提交給ECMA制定為標準,稱之為ECMAScript,標準編號ECMA-262。使用顯式版本號聲明對語言的參照,作為一項Mozilla的特性,已在較新版本中被移除(至少為Firefox 59)。Firefox 4是最後一個需要顯式地在參照時聲明明確版本號的版本(1.8.5)。

下列表格的資訊基於多個參考來源[45][46][47][48]

版本 發佈日期 基於 Netscape
Navigator
Mozilla
Firefox
Internet
Explorer
Opera Safari Google
Chrome
舊版本,不再支援: 1.0 1996年3月 2.0 3.0
舊版本,不再支援: 1.1 1996年8月 3.0
舊版本,不再支援: 1.2 1997年6月 4.0 - 4.05 3
舊版本,不再支援: 1.3 1998年10月 ECMA-262 1st + 2nd edition 4.06 - 4.7x 4.0 5[49]
舊版本,不再支援: 1.4 Netscape
Server
6
舊版本,不再支援: 1.5 2000年11月 ECMA-262 3rd edition 6.0 1.0 5.5(JScript 5.5)
6(JScript 5.6)
7(JScript 5.7)
8(JScript 5.8)
7.0 3.0-5 1.0 - 10.0.666
舊版本,不再支援: 1.6 2005年11月 1.5 + Array extras + Array and string generics + E4X 1.5
舊版本,不再支援: 1.7 2006年10月 1.6 + Pythonic generators + Iterators + Let 2.0 28.0.1500.95
舊版本,不再支援: 1.8 2008年6月 1.7 + Generator expressions + Expression closures 3.0 11.50
舊版本,不再支援: 1.8.1 1.8 + native JSON support + Minor updates 3.5
舊版本,不再支援: 1.8.2 2009年6月22日 1.8.1 + Minor updates 3.6
舊版本,不再支援: 1.8.5 2010年7月27日 1.8.2 + New features for ECMA-262 5th edition compliance 4.0

參見

參考文獻

  1. 1.0 1.1 Press release announcing JavaScript, "Netscape and Sun announce JavaScript", PR Newswire, December 4, 1995
  2. Standard ECMA-262. Ecma International. 2017-07-03 [2020-02-16]. 
  3. nodejs/node-eps. GitHub. [2020-02-16]. 
  4. "Coders at Work: Reflections on the Craft of Programming". 
  5. RFC 4329. [2012-03-02]. 
  6. System-Declared Uniform Type Identifiers. Mac OS X Reference Library. Apple Inc. [2010-03-05]. 
  7. 7.0 7.1 David, Flanagan. JavaScript: The Definitive Guide 6th. O'Reilly & Associates. ISBN 978-0-596-80552-4. 
  8. 8.0 8.1 ECMAScript Language Overview (PDF): 4. 2007-10-23 [2009-05-03]. 
  9. JavaScript: The World's Most Misunderstood Programming Language. www.crockford.com. [2016-08-17]. 
  10. Bloomberg Game Changers: Marc Andreessen. Bloomberg. 2011-03-17 [2011-12-07]. 
  11. Enzer, Larry. The Evolution of the Web Browsers. Monmouth Web Developers. 2018-08-31 [2018-08-31]. 
  12. Chapter 4. How JavaScript Was Created. [2018-07-14]. 
  13. Severance, Charles. JavaScript: Designing a Language in 10 Days. Computer (IEEE Computer Society). 2012-02, 45 (2): 7–8 [2013-03-23]. doi:10.1109/MC.2012.57. 
  14. TechVision: Innovators of the Net: Brendan Eich and JavaScript (HTML). 2009-03-19 [2009-03-19]. 
  15. TechVision: Innovators of the Net: Brendan Eich and JavaScript. web.archive.org. [2009-03-19]. 
  16. 16.0 16.1 Champeon, Steve. JavaScript, How Did We Get Here?. oreilly.com. 2001-04-06 [2016-07-16]. 
  17. Microsoft Internet Explorer 3.0 Beta Now Available. microsoft.com. Microsoft. 1996-05-29 [2016-07-16]. 
  18. McCracken, Harry. The Unwelcome Return of "Best Viewed with Internet Explorer". technologizer.com. 2010-09-16 [2016-07-16]. 
  19. Nicholas, Zakas. Professional JavaScript for Web Developers 3rd. Wrox. 2012. ISBN 978-1-118-02669-4. 
  20. 存档副本. [2020-07-09]. 
  21. 存档副本. [2020-07-09]. 
  22. 存档副本. [2020-07-09]. 
  23. 存档副本. [2020-07-09]. 
  24. 存档副本. [2020-07-09]. 
  25. 存档副本. [2020-07-09]. 
  26. 存档副本. [2020-07-09]. 
  27. 存档副本. [2020-07-09]. 
  28. 存档副本. [2020-07-09]. 
  29. 存档副本. [2020-07-09]. 
  30. 存档副本. [2020-07-09]. 
  31. 存档副本. [2020-07-09]. 
  32. 使用物件 - JavaScript | MDN
  33. 存档副本. [2020-07-09]. 
  34. 存档副本. [2020-07-09]. 
  35. 存档副本. [2020-07-09]. 
  36. 存档副本. [2020-07-09]. 
  37. 存档副本. [2020-07-09]. 
  38. 存档副本. [2020-07-09]. 
  39. 存档副本. [2020-07-09]. 
  40. 存档副本. [2020-07-09]. 
  41. 存档副本. [2020-07-09]. 
  42. 存档副本. [2020-07-09]. 
  43. 存档副本. [2020-07-09]. 
  44. 存档副本. [2020-07-09]. 
  45. New in JavaScript. developer.mozilla.org. 2014 [2016-07-16]. 
  46. JavaScript – JScript – ECMAScript version history. Webmasterworld.com. [2009-12-17]. 
  47. John Resig. Versions of JavaScript. Ejohn.org. [2009-05-19]. 
  48. Version Information (JScript). Msdn.microsoft.com. [2009-12-17]. 
  49. What Version of JavaScript. [2016-08-27]. 

外部連結