JavaScript（通常縮寫為 JS）是一門基於原型和頭等函式的多正規化高階 zhhans 解釋型；zhhant 直譯 程式語言，它支援面向物件程式設計、指令式程式設計和函數語言程式設計。它提供方法來操控文字、陣列、日期以及正則表示式等。不支援 IO，比如網路、儲存和圖形等，但這些都可以由它的宿主環境提供支援。它由 Ecma 透過 ECMAScript 實現語言的標準化。目前，它被世界上的絕大多數網站所使用，也被世界主流瀏覽器（Chrome、Firefox、Safari 和 Opera）所支援。 JavaScript 與 Java 在名字和語法上都很相似，但這兩門程式語言從設計之初就有很大不同。JavaScript 在語言設計上主要受到了 Self（一種基於原型的程式語言）和 Scheme（一門函數語言程式設計語言）的影響，在語法結構上它和 C 語言很相似（如 if 條件語句、switch 語句、while 迴圈和 dowhile 迴圈等）。 對於客戶端來說，JavaScript 通常被實現為一門解釋語言，但如今它已經可以被即時編譯（JIT）。隨著 HTML5 和 CSS3 語言標準的推行，它還可以用於遊戲、桌面和移動應用程式的開發，以及在伺服器端網路環境執行（如 Nodejs）。 歷史 肇始於網景 1993 年，國家超級電腦應用中心（NCSA）發表了 NCSA Mosaic，這是最早流行的圖形介面網頁瀏覽器，它在全球資訊網的普及上發揮了重要作用。1994 年，Mosaic 的主要開發人員創立了 Netscape 公司，並僱用了許多原來的 NCSA Mosaic 開發者用來開發 Netscape Navigator，該公司的目標是取代 NCSA Mosaic 成為世界第一的網頁瀏覽器。在四個月內，已經佔據了四分之三的瀏覽器市場，並成為 1990 年代網際網路的主要瀏覽器。 在網路發展的這些年，網頁只能是靜態的，缺乏在瀏覽器中載入網頁後的動態行為能力。公司的創始人馬克安德森認為 HTML 需要一種膠水語言，讓網頁設計師和兼職程式設計師可以很容易地使用它來組裝圖片和外掛程式之類的元件，且程式碼可以直接編寫在網頁標記中。1995 年，網景招募了布蘭登艾克，目標是把 Scheme 語言嵌入到 Netscape Navigator 瀏覽器中。但更早之前，網景已經跟昇陽合作，計劃在 Netscape Navigator 中嵌入 Java 語言，這時網景內部產生激烈的爭論， 網景公司管理層很快決定，最佳的方案是由艾克設計一種新的語言，其語法類似於 Java，而不像 Scheme 或其他現存的指令碼語言。為了在其他競爭提案中捍衛 JavaScript 這個想法，公司需要有一個可以運作的原型。艾克在 1995 年 5 月僅花了十天時間就把原型設計出來了。最初命名為 Mocha，1995 年 9 月在 Netscape Navigator 20 的 Beta 版中改名為 LiveScript，同年 12 月在 Netscape Navigator 20 Beta 3 中部署時又被重新命名為 JavaScript，這是因為當時網景公司與昇陽電腦公司組成的開發聯盟為了讓這門語言搭上 Java 這個程式語言 熱詞，所以才將其臨時改名為 JavaScript，這成了日後這成為大眾對這門語言有諸多誤解的原因之一。同年昇陽電腦公司在 1995 年 12 月 1 日正式申請註冊 JavaScript 的商標，於 2000 年 7 月 28 日獲批 ，但此後昇陽電腦公司和之後收購它的甲骨文公司從未使用該商標製造過產品，給 JavaScript 社群帶來了不確定性，阻礙了 JavaScript 社群的自由發展，直到幾十年後，15 萬多名 JavaScript 社群成員於 2024 年 11 月 22 日聯名向美國專利商標局申請終止該商標 。 微軟採納 微軟公司於 1995 年首次推出 Internet Explorer，引發了與 Netscape 的瀏覽器大戰。微軟對 Netscape Navigator 直譯器進行了逆向工程，建立了 JScript，以與處於市場領導地位的網景產品同臺競爭。JScript 也是一種 JavaScript 實作，這兩個 JavaScript 語言版本在瀏覽器端共存意味著語言標準化的缺失。發展初期，JavaScript 的標準並未確定，同期就有網景的 JavaScript 和微軟的 JScript。除此之外，微軟也在網頁技術上加入了不少專屬物件，使不少網頁使用非微軟平臺及瀏覽器無法正常顯示。這導致在瀏覽器大戰期間網頁設計者通常會把「用 Netscape 可達到最佳效果」或「用 IE 可達到最佳效果」的標誌放在首頁。 標準化 1996 年 11 月，網景正式向 ECMA（歐洲計算機制造商協會）提交語言標準。1997 年 6 月，ECMA 以 JavaScript 語言為基礎制定了 ECMAScript 標準規範 ECMA262。JavaScript 成為了 ECMAScript 最著名的實現之一。除此之外，ActionScript 和 JScript 也都是 ECMAScript 規範的實現語言。儘管 JavaScript 作為給非程式人員的指令碼語言，而非作為給程式人員的程式語言來推廣和宣傳，但是 JavaScript 具有非常豐富的特性。 增長和標準化 在 21 世紀初 Internet Explorer 占主導地位期間，客戶端指令碼停滯不前。這在 2004 年開始改變，當時 Netscape 的繼任者 Mozilla 釋出了 Firefox 瀏覽器。Firefox 受到許多人的好評，從 Internet Explorer 獲得了巨大的市場份額。 2005 年，Mozilla 加入了 ECMA International，並開始研究 ECMAScript for XML（E4X）標準。這導致 Mozilla 與 Macromedia（後來被 Adobe Systems 收購）合作，他們正在用基於 ECMAScript 4 草案的 ActionScript 3 語言實現 E4X。目標是將 ActionScript 3 標準化為新的 ECMAScript 4。為此，Adobe Systems 將 Tamarin 實現作為開源專案釋出。然而，Tamarin 和 ActionScript 3 與既定的客戶端指令碼太不同，如果沒有微軟的合作，ECMAScript 4 從未取得成果。 與此同時，與 ECMA 工作無關的開源社群正在發生非常重要的發展。2005 年，Jesse James Garrett 釋出了一份白皮書，其中他創造了 Ajax 一詞，並描述了一套技術，其中 JavaScript 是骨幹，用於建立可以在後臺載入資料的 Web 應用程式，避免了重新載入整頁的需要。這引發了 JavaScript 的復興時期，由開源庫和圍繞它們形成的社群帶頭。建立了許多新庫，包括 jQuery、Prototype、Dojo Toolkit 和 MooTools。 谷歌於 2008 年首次推出 Chrome 瀏覽器，其 V8 JavaScript 引擎比競爭對手更快。關鍵的創新是及時編譯（JIT），因此其他瀏覽器供應商需要為 JIT 徹底改革他們的引擎 2008 年 7 月，這些不同的政黨聚集在一起，在奧斯陸舉行會議。這導致在 2009 年初達成了最終協議，將所有相關工作結合起來，推動語言向前發展。結果是 2009 年 12 月釋出的 ECMAScript 5 標準。 走向成熟 關於該語言的雄心勃勃的工作持續了數年，最終隨著 2015 年 ECMAScript 6 的釋出而正式形成了廣泛的補充和改進。 Ryan Dahl 在 2009 年建立的 Nodejs 引發了 Web 瀏覽器之外 JavaScript 使用的顯著增加。Node 結合了 V8 引擎、事件迴圈和 IO API，從而提供了獨立的 JavaScript 執行時系統。截至 2018 年，Node 已被數百萬開發人員使用，並且 npm 擁有世界上所有包管理器中最多的模組。 ECMAScript 草案規範目前在 GitHub 上公開維護，並透過定期的年度快照生成版本。對語言的潛在修訂透過全面的提案流程進行審查。現在，開發人員不再單獨檢查即將推出的功能的狀態，而不是版本號。 當前的 JavaScript 生態系統擁有許多庫和框架、已建立的程式設計實踐以及在 Web 瀏覽器之外大量使用 JavaScript。另外，隨著單頁應用程式和其他大量使用 JavaScript 的網站的興起，已經建立了多個轉譯器來幫助開發過程。 概論 一般來說，完整的 JavaScript 包括以下幾個部分： ECMAScript，描述了該語言的語法和基本物件； 文件物件模型（DOM），描述處理網頁內容的方法和介面； 瀏覽器物件模型（BOM），描述與瀏覽器進行互動的方法和介面。 JavaScript 的基本特點如下： 是一種解釋性指令碼語言（程式碼不進行預編譯）； 主要用來向 HTML 頁面新增互動行為； 可以直接嵌入 HTML 頁面，但寫成單獨的 js 檔案有利於結構和行為的分離。 JavaScript 常用來完成以下任務： 嵌入動態文字於 HTML 頁面； 對瀏覽器事件作出響應； 讀寫 HTML 元素； 在資料被提交到伺服器之前驗證資料； 檢測訪客的瀏覽器資訊； 控制 Cookie，包括建立和修改等； 特性 不同於伺服器端指令碼語言（如 PHP 和 ASP），JavaScript 主要被作為客戶端指令碼語言在使用者的瀏覽器上執行，不需要伺服器的支援。所以在早期程式設計師比較青睞於 JavaScript 以減少對伺服器的負擔，而與此同時在安全性上出現了問題。隨著伺服器變得強大，現在的程式設計師更喜歡執行於伺服器端的指令碼以保證安全，但 JavaScript 仍然以其跨平臺、容易上手等優勢大行其道。同時，有些特殊功能（如 AJAX）必須依賴 JavaScript 在客戶端提供支援。隨著引擎（如 V8）和框架（如 Nodejs）的發展，以及事件驅動和非同步 IO 等特性，JavaScript 也被逐漸用來編寫伺服器端程式。 以下是 ECMAScript 通常所實現的特性。 指令式與結構化 JavaScript 支援許多 C 語言的結構化程式設計語法（如 if 條件語句、while 迴圈、switch 語句和 dowhile 迴圈等），但作用域是一個例外。JavaScript 在過去只支援使用 var 關鍵字來定義變數的函式作用域，但 ECMAScript 2015 中加入了 let 關鍵字來支援塊級作用域。這意味著 JavaScript 現在既支援函式作用域又支援塊級作用域。JavaScript 還支援自動在語句末新增分號，允許忽略語句末尾的分號。 弱型別 JavaScript 是弱型別的，這意味著變數可以被隱式轉換為另一個型別。 二元運算子 會把兩個運算元轉換為字串，除非兩個運算元都為數字型別。這是因為 也表示字串連線操作； 二元運算子 會把兩個運算元轉換為數字型別； 一元運算子，包括 和 ，都會把運算元轉換為數字。 下列為變數轉換為字串的例子： 字串型別不變； 數字會轉換為其字串表示； 陣列的元素會轉換為字串，然後連線成透過逗號，分隔的長字串； 其它物件會轉換為 object Object，其中 Object 中該物件的建構函式名。 型別的隱藏轉換是 JavaScript 受到批評的原因之一，因為隱藏轉換增加了規則的複雜度和發生錯誤的可能性。 JavaScript 中的隱式轉換 左運算元 運算子 右運算元 結果 （空陣列） （空陣列） （空字串） （空陣列） （空物件） object Object（字串） false（布林值） （空字串）false（字串）123（字串） 1（數字）1231（字串）123（字串） 1（數字） 122 （數字） 動態化 型別 JavaScript 是動態型別的語言，其型別與值而不是與變數相關聯。例如變數可以為數字，隨後又可被賦值為字串。JavaScript 提供了包括鴨子型別在內的方法來檢測變數型別。 執行時估值 JavaScript 提供 eval 函式，可以在執行時直接執行 JavaScript 語句。 基於原型的面向物件 在 JavaScript 中，物件是關聯陣列，透過原型（prototype，見下）進行擴充。每一個字串鍵值提供物件的一個屬性的名稱，可以透過使用點號（objx）或使用方括號（obj x）這兩種效果相同的方式來訪問。屬性可以在執行時新增、重定義或刪除。一個物件的大多數屬性（包括來自原型繼承鏈的屬性）都可以透過 forin 迴圈訪問。 原型 JavaScript 使用原型，而許多其它面嚮物件語言使用類用於實現繼承。原型使得在 JavaScript 中模擬基於類的面向物件特徵變成可能。 函式作為物件構造器 函式在 JavaScript 中兼作為物件建構函式。在函式呼叫前加上 new 會建立一個原型的例項，並繼承來自建構函式的屬性和方法（包括來自 Object 原型）。ECMAScript 5 提供 Objectcreate 方法，可以顯式地建立例項而不是自動從 Object 繼承。建構函式的 prototype 屬性決定了用於新物件的內部原型。可以透過修改建構函式的原型的方法來為物件新增新的方法，也可以修改 JavaScript 的內部物件的原型（如 Array 或 Object）。儘管可以這麼做，但對 Object 原型進行修改並不是好的做法。因為大多數 JavaScript 物件都會從 Object 繼承，且不會希望其原型被修改。 函式作為方法 和大多數面向物件的語言不同，在 JavaScript 中函式定義和方法定義沒有明顯區別。唯一的區別在於呼叫時：當函式被作為方法呼叫時，函式的 this 會指向呼叫此函式的物件。 傳統的類定義與使用格式 ECMAScript 2015 中加入了對 class 和 extends 關鍵字的支援，使得類的定義與繼承更類似於其他的面嚮物件語言，同時也更易使用。 函式式 在 JavaScript 中，函式是一等的，函式也被認為是物件。因此，函式可以有屬性和方法，例如 call 和 bind 等。巢狀函式指定義於其它函式內部的函式，在外部函式被呼叫時，巢狀函式會被建立。另外，巢狀函式是一個閉包，在外部函式的作用域（包括常量，區域性變數和引數）都成為內部函式狀態的一部分，甚至在外部函式執行完畢後，內部函式的狀態依然保留。JavaScript 同時也支援匿名函式。 其它 執行時環境 JavaScript 通常依賴於執行時環境（例如瀏覽器）來提供物件和方法，指令碼可以透過這些物件和方法與環境（例如網頁 DOM）進行互動。它還依賴於執行時環境來提供包或匯入指令碼（例如 HTML 的 script 元素）的功能。這本身不是語言功能，但在大多數 JavaScript 實現中很常見。 承諾 JavaScript 的 承諾（Promise）是一種程式設計模型，它允許表示可能在未來某個時間點完成或失敗的值。承諾被設計為一個解決非同步程式設計中所遇到的問題的更簡潔和一致的方法。相比於傳統的回撥函式，它為處理非同步操作提供了一個更清晰的方式。 一個承諾有三種狀態： 待定（Pending） 初始狀態，既不是成功也不是失敗。 已履行（Fulfilled） 意味著操作成功完成。 已拒絕（Rejected） 意味著操作失敗。 承諾的主要特點是它們的狀態一旦改變（從待定到已履行或已拒絕），就不能再次改變。這使得承諾成為一個可靠的資訊來源，無論它們是否成功。 在 JavaScript 中，你可以使用 then 方法來附加回調函式，這些回撥函式會在承諾達到已履行或已拒絕狀態時執行。還有一個 catch 方法，專門用於處理被拒絕的承諾。為了使鏈式呼叫更簡潔，then 和 catch 都會返回一個新的承諾。ES6（ECMAScript 2015）引入了原生的 Promise 物件，從此承諾成為 JavaScript 標準的一部分。此後的版本還提供了額外的實用方法，例如 Promiseall 和 Promiserace ，用於處理多個承諾。 非同步 JavaScript 一般來說是單執行緒的。為了併發地處理事件，JavaScript 程式輸入或輸出時使用事件和回撥函式執行。這意味著 JavaScript 可以在等待資料庫查詢返回資訊之前處理滑鼠單擊。ECMAScript 2015 引入了 Promise 用於處理非同步事件，其可以使得傳統的基於回撥的非同步程式碼更加清晰簡單。 變長引數 JavaScript 中函式引數的長度是可變的，在函式內部可以透過 arguments 物件訪問這些引數。 程式設計 JavaScript 是一門指令碼語言，其原始碼在客戶端執行前不需經過編譯，而是將文字格式的字元程式碼傳送給瀏覽器，由瀏覽器解釋執行。直譯語言的弱點是安全性較差，而且在 JavaScript 中，如果一條語句執行不了，通常它下面的語言也就無法執行。解決辦法是使用異常處理 try catch zhhans consolelog a 這是正確的 consolelog b 這是正確的 consolelogg c 這是錯誤的，並且到這裡會停下來 consolelog d 這是正確的 consolelog e 這是正確的 解決辦法 try consolelog a catch e 這是正確的 try consolelog b catch e 這是正確的 try consolelogg c catch e 這是錯誤的，但是到這裡不會停下來，而是跳過 try consolelog d catch e 這是正確的 try consolelog e catch e 這是正確的 zhhant consolelog a 這是正確的 consolelog b 這是正確的 consolelogg c 這是錯誤的，並且到這裡會停下來 consolelog d 這是正確的 consolelog e 這是正確的 解決辦法 try consolelog a catch e 這是正確的 try consolelog b catch e 這是正確的 try consolelogg c catch e 這是錯誤的，但是到這裡不會停下來，而是跳過 try consolelog d catch e 這是正確的 try consolelog e catch e 這是正確的 JavaScript 被歸類為直譯語言，因為主流的引擎都是每次執行時載入程式碼並解譯。V8 是將所有程式碼解譯後再開始執行，其他引擎則是逐行解譯（SpiderMonkey 會將解譯過的指令暫存，以提高效能，稱為即時編譯）。但由於 V8 的核心部份多數用 JavaScript 撰寫（而 SpiderMonkey 是用 C），因此在不同的測試上，兩者效能互有優劣。 與其相對應的是編譯語言（如 C 語言），以編譯語言編寫的程式在執行之前必須經過編譯，將程式碼編譯為機器碼，才可以執行。 範例 以下是一個簡單的 JavaScript Hello World zhhans DOCTYPE HTML html head title 簡單的 JavaScript Hello Worldtitle script documentwrite Hello world 直接插入頁面中 alert Hello world 彈窗顯示 consolelog Hello world 在控制檯（console）裡顯示，需要先開啟開發工具控制檯 script head body HTML 內容 body html zhhant DOCTYPE HTML html head title 簡單的 JavaScript Hello Worldtitle script documentwrite Hello world 於瀏覽器視窗內直接顯示 alert Hello world 開啟對話視窗顯示 consolelog Hello world 於 console 裡顯示，需要先開啟開發工具控制檯 script head body HTML 內容 body html 或是在瀏覽器的位址列中使用 javascript，以互動方式表示： javascriptalert Hello world 版本 JavaScript 最初開發於 1996 年，被使用於 Netscape Navigator 網頁瀏覽器。同年微軟在 Internet Explorer 發布了一個實作。由於商標問題，這項實作被命名為 JScript。1997 年，JavaScript 已經被網景公司提交給 ECMA 制定為標準，稱之為 ECMAScript，標準編號 ECMA262。使用顯式版本號宣告對語言的引用，作為一項 Mozilla 的特性，已在較新版本中被移除（至少為 Firefox 59）。Firefox 4 是最後一個需要顯式地在引用時宣告明確版本號的版本（185）。 下列表格的資訊基於多個參考來源： 版本 發布日期 基於 NetscapeNavigator MozillaFirefox InternetExplorer Opera Safari GoogleChrome 1996 年 3 月 20 30 1996 年 8 月 30 1997 年 6 月 40 405 3 1998 年 10 月 ECMA262 1st 2nd edition 406 47x 40 5 NetscapeServer 6 2000 年 11 月 ECMA262 3rd edition 60 10 55（JScript 55）6（JScript 56）7（JScript 57）8（JScript 58） 70 305 10 100666 2005 年 11 月 15 Array extras Array and string generics E4X 15 2006 年 10 月 16 Pythonic generatorsPythonic generators Iterators Let 20 280150095 2008 年 6 月 17 Generator expressions Expression closures 30 1150 18 native JSON support Minor updates 35 2009 年 6 月 22 日 181 Minor updates 36 2010 年 7 月 27 日 182 New features for ECMA262 5th edition compliance 40 參見 指令碼語言 DMDScript ECMAScript JavaScript 引擎 JScript AJAX JavaScript 函式庫 參考文獻 外部連結 關於 JavaScript 介紹 Mozilla Developer Network 上的資源 Category 美國發明 Category 跨平臺軟體 Category 函數語言程式設計語言 CategoryISO 標準化程式語言 Category 指令碼語言 Category 基於原型的程式語言 Category 基於物件的程式語言 Category1995 年建立的程式語言