JavaScript 是一種輕量級(jí)的腳本語言。所謂“腳本語言”(script language),指的是它不具備開發(fā)操作系統(tǒng)的能力,而是只用來編寫控制其他大型應(yīng)用程序(比如瀏覽器)的“腳本”。
JavaScript 也是一種嵌入式(embedded)語言。它本身提供的核心語法不算很多,只能用來做一些數(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)境有多種,最常見的環(huán)境就是瀏覽器,另外還有服務(wù)器環(huán)境,也就是 Node 項(xiàng)目。
從語法角度看,JavaScript 語言是一種“對(duì)象模型”語言。各種宿主環(huán)境通過這個(gè)模型,描述自己的功能和操作接口,從而通過 JavaScript 控制這些功能。但是,JavaScript 并不是純粹的“面向?qū)ο笳Z言”,還支持其他編程范式(比如函數(shù)式編程)。這導(dǎo)致幾乎任何一個(gè)問題,JavaScript 都有多種解決方法。閱讀本書的過程中,你會(huì)詫異于 JavaScript 語法的靈活性。
JavaScript 的核心語法部分相當(dāng)精簡(jiǎn),只包括兩個(gè)部分:基本的語法構(gòu)造(比如操作符、控制結(jié)構(gòu)、語句)和標(biāo)準(zhǔn)庫(就是一系列具有各種功能的對(duì)象比如Array
、Date
、Math
等)。除此之外,各種宿主環(huán)境提供額外的 API(即只能在該環(huán)境使用的接口),以便 JavaScript 調(diào)用。以瀏覽器為例,它提供的額外 API 可以分成三大類。
如果宿主環(huán)境是服務(wù)器,則會(huì)提供各種操作系統(tǒng)的 API,比如文件操作 API、網(wǎng)絡(luò)通信 API等等。這些你都可以在 Node 環(huán)境中找到。
本書主要介紹 JavaScript 核心語法和瀏覽器網(wǎng)頁開發(fā)的基本知識(shí),不涉及 Node。全書可以分成以下四大部分。
JavaScript 語言有多個(gè)版本。本書的內(nèi)容主要基于 ECMAScript 5.1 版本,這是學(xué)習(xí) JavaScript 語法的基礎(chǔ)。ES6 和更新的語法請(qǐng)參考我寫的《ECMAScript 6入門》。
JavaScript 語言有一些顯著特點(diǎn),使得它非常值得學(xué)習(xí)。它既適合作為學(xué)習(xí)編程的入門語言,也適合當(dāng)作日常開發(fā)的工作語言。它是目前最有希望、前途最光明的計(jì)算機(jī)語言之一。
JavaScript 的發(fā)明目的,就是作為瀏覽器的內(nèi)置腳本語言,為網(wǎng)頁開發(fā)者提供操控瀏覽器的能力。它是目前唯一一種通用的瀏覽器腳本語言,所有瀏覽器都支持。它可以讓網(wǎng)頁呈現(xiàn)各種特殊效果,為用戶提供良好的互動(dòng)體驗(yàn)。
目前,全世界幾乎所有網(wǎng)頁都使用 JavaScript。如果不用,網(wǎng)站的易用性和使用效率將大打折扣,無法成為操作便利、對(duì)用戶友好的網(wǎng)站。
對(duì)于一個(gè)互聯(lián)網(wǎng)開發(fā)者來說,如果你想提供漂亮的網(wǎng)頁、令用戶滿意的上網(wǎng)體驗(yàn)、各種基于瀏覽器的便捷功能、前后端之間緊密高效的聯(lián)系,JavaScript 是必不可少的工具。
近年來,JavaScript 的使用范圍,慢慢超越了瀏覽器,正在向通用的系統(tǒng)語言發(fā)展。
(1)瀏覽器的平臺(tái)化
隨著 HTML5 的出現(xiàn),瀏覽器本身的功能越來越強(qiáng),不再僅僅能瀏覽網(wǎng)頁,而是越來越像一個(gè)平臺(tái),JavaScript 因此得以調(diào)用許多系統(tǒng)功能,比如操作本地文件、操作圖片、調(diào)用攝像頭和麥克風(fēng)等等。這使得 JavaScript 可以完成許多以前無法想象的事情。
(2)Node
Node 項(xiàng)目使得 JavaScript 可以用于開發(fā)服務(wù)器端的大型項(xiàng)目,網(wǎng)站的前后端都用 JavaScript 開發(fā)已經(jīng)成為了現(xiàn)實(shí)。有些嵌入式平臺(tái)(Raspberry Pi)能夠安裝 Node,于是 JavaScript 就能為這些平臺(tái)開發(fā)應(yīng)用程序。
(3)數(shù)據(jù)庫操作
JavaScript 甚至也可以用來操作數(shù)據(jù)庫。NoSQL 數(shù)據(jù)庫這個(gè)概念,本身就是在 JSON(JavaScript Object Notation)格式的基礎(chǔ)上誕生的,大部分 NoSQL 數(shù)據(jù)庫允許 JavaScript 直接操作。基于 SQL 語言的開源數(shù)據(jù)庫 PostgreSQL 支持 JavaScript 作為操作語言,可以部分取代 SQL 查詢語言。
(4)移動(dòng)平臺(tái)開發(fā)
JavaScript 也正在成為手機(jī)應(yīng)用的開發(fā)語言。一般來說,安卓平臺(tái)使用 Java 語言開發(fā),iOS 平臺(tái)使用 Objective-C 或 Swift 語言開發(fā)。許多人正在努力,讓 JavaScript 成為各個(gè)平臺(tái)的通用開發(fā)語言。
PhoneGap 項(xiàng)目就是將 JavaScript 和 HTML5 打包在一個(gè)容器之中,使得它能同時(shí)在 iOS 和安卓上運(yùn)行。Facebook 公司的 React Native 項(xiàng)目則是將 JavaScript 寫的組件,編譯成原生組件,從而使它們具備優(yōu)秀的性能。
Mozilla 基金會(huì)的手機(jī)操作系統(tǒng) Firefox OS,更是直接將 JavaScript 作為操作系統(tǒng)的平臺(tái)語言,但是很可惜這個(gè)項(xiàng)目沒有成功。
(5)內(nèi)嵌腳本語言
越來越多的應(yīng)用程序,將 JavaScript 作為內(nèi)嵌的腳本語言,比如 Adobe 公司的著名 PDF 閱讀器 Acrobat、Linux 桌面環(huán)境 GNOME 3。
(6)跨平臺(tái)的桌面應(yīng)用程序
Chromium OS、Windows 8 等操作系統(tǒng)直接支持 JavaScript 編寫應(yīng)用程序。Mozilla 的 Open Web Apps 項(xiàng)目、Google 的 Chrome App 項(xiàng)目、GitHub 的 Electron 項(xiàng)目、以及 TideSDK 項(xiàng)目,都可以用來編寫運(yùn)行于 Windows、Mac OS 和 Android 等多個(gè)桌面平臺(tái)的程序,不依賴瀏覽器。
(7)小結(jié)
可以預(yù)期,JavaScript 最終將能讓你只用一種語言,就開發(fā)出適應(yīng)不同平臺(tái)(包括桌面端、服務(wù)器端、手機(jī)端)的程序。早在2013年9月的統(tǒng)計(jì)之中,JavaScript 就是當(dāng)年 GitHub 上使用量排名第一的語言。
著名程序員 Jeff Atwood 甚至提出了一條 “Atwood 定律”:
“所有可以用 JavaScript 編寫的程序,最終都會(huì)出現(xiàn) JavaScript 的版本。”(Any application that can be written in JavaScript will eventually be written in JavaScript.)
相比學(xué)習(xí)其他語言,學(xué)習(xí) JavaScript 有一些有利條件。
(1)學(xué)習(xí)環(huán)境無處不在
只要有瀏覽器,就能運(yùn)行 JavaScript 程序;只要有文本編輯器,就能編寫 JavaScript 程序。這意味著,幾乎所有電腦都原生提供 JavaScript 學(xué)習(xí)環(huán)境,不用另行安裝復(fù)雜的 IDE(集成開發(fā)環(huán)境)和編譯器。
(2)簡(jiǎn)單性
相比其他腳本語言(比如 Python 或 Ruby),JavaScript 的語法相對(duì)簡(jiǎn)單一些,本身的語法特性并不是特別多。而且,那些語法中的復(fù)雜部分,也不是必需要學(xué)會(huì)。你完全可以只用簡(jiǎn)單命令,完成大部分的操作。
(3)與主流語言的相似性
JavaScript 的語法很類似 C/C++ 和 Java,如果學(xué)過這些語言(事實(shí)上大多數(shù)學(xué)校都教),JavaScript 的入門會(huì)非常容易。
必須說明的是,雖然核心語法不難,但是 JavaScript 的復(fù)雜性體現(xiàn)在另外兩個(gè)方面。
首先,它涉及大量的外部 API。JavaScript 要發(fā)揮作用,必須與其他組件配合,這些外部組件五花八門,數(shù)量極其龐大,幾乎涉及網(wǎng)絡(luò)應(yīng)用的各個(gè)方面,掌握它們絕非易事。
其次,JavaScript 語言有一些設(shè)計(jì)缺陷。某些地方相當(dāng)不合理,另一些地方則會(huì)出現(xiàn)怪異的運(yùn)行結(jié)果。學(xué)習(xí) JavaScript,很大一部分時(shí)間是用來搞清楚哪些地方有陷阱。Douglas Crockford 寫過一本有名的書,名字就叫《JavaScript: The Good Parts》,言下之意就是這門語言不好的地方很多,必須寫一本書才能講清楚。另外一些程序員則感到,為了更合理地編寫 JavaScript 程序,就不能用 JavaScript 來寫,而必須發(fā)明新的語言,比如 CoffeeScript、TypeScript、Dart 這些新語言的發(fā)明目的,多多少少都有這個(gè)因素。
盡管如此,目前看來,JavaScript 的地位還是無法動(dòng)搖。加之,語言標(biāo)準(zhǔn)的快速進(jìn)化,使得 JavaScript 功能日益增強(qiáng),而語法缺陷和怪異之處得到了彌補(bǔ)。所以,JavaScript 還是值得學(xué)習(xí),況且它的入門真的不難。
JavaScript 的性能優(yōu)勢(shì)體現(xiàn)在以下方面。
(1)靈活的語法,表達(dá)力強(qiáng)。
JavaScript 既支持類似 C 語言清晰的過程式編程,也支持靈活的函數(shù)式編程,可以用來寫并發(fā)處理(concurrent)。這些語法特性已經(jīng)被證明非常強(qiáng)大,可以用于許多場(chǎng)合,尤其適用異步編程。
JavaScript 的所有值都是對(duì)象,這為程序員提供了靈活性和便利性。因?yàn)槟憧梢院芊奖愕?、按照需要隨時(shí)創(chuàng)造數(shù)據(jù)結(jié)構(gòu),不用進(jìn)行麻煩的預(yù)定義。
JavaScript 的標(biāo)準(zhǔn)還在快速進(jìn)化中,并不斷合理化,添加更適用的語法特性。
(2)支持編譯運(yùn)行。
JavaScript 語言本身,雖然是一種解釋型語言,但是在現(xiàn)代瀏覽器中,JavaScript 都是編譯后運(yùn)行。程序會(huì)被高度優(yōu)化,運(yùn)行效率接近二進(jìn)制程序。而且,JavaScript 引擎正在快速發(fā)展,性能將越來越好。
此外,還有一種 WebAssembly 格式,它是 JavaScript 引擎的中間碼格式,全部都是二進(jìn)制代碼。由于跳過了編譯步驟,可以達(dá)到接近原生二進(jìn)制代碼的運(yùn)行速度。各種語言(主要是 C 和 C++)通過編譯成 WebAssembly,就可以在瀏覽器里面運(yùn)行。
(3)事件驅(qū)動(dòng)和非阻塞式設(shè)計(jì)。
JavaScript 程序可以采用事件驅(qū)動(dòng)(event-driven)和非阻塞式(non-blocking)設(shè)計(jì),在服務(wù)器端適合高并發(fā)環(huán)境,普通的硬件就可以承受很大的訪問量。
JavaScript 是一種開放的語言。它的標(biāo)準(zhǔn) ECMA-262 是 ISO 國(guó)際標(biāo)準(zhǔn),寫得非常詳盡明確;該標(biāo)準(zhǔn)的主要實(shí)現(xiàn)(比如 V8 和 SpiderMonkey 引擎)都是開放的,而且質(zhì)量很高。這保證了這門語言不屬于任何公司或個(gè)人,不存在版權(quán)和專利的問題。
語言標(biāo)準(zhǔn)由 TC39 委員會(huì)負(fù)責(zé)制定,該委員會(huì)的運(yùn)作是透明的,所有討論都是開放的,會(huì)議記錄都會(huì)對(duì)外公布。
不同公司的 JavaScript 運(yùn)行環(huán)境,兼容性很好,程序不做調(diào)整或只做很小的調(diào)整,就能在所有瀏覽器上運(yùn)行。
全世界程序員都在使用 JavaScript,它有著極大的社區(qū)、廣泛的文獻(xiàn)和圖書、豐富的代碼資源。絕大部分你需要用到的功能,都有多個(gè)開源函數(shù)庫可供選用。
作為項(xiàng)目負(fù)責(zé)人,你不難招聘到數(shù)量眾多的 JavaScript 程序員;作為開發(fā)者,你也不難找到一份 JavaScript 的工作。
本教程包含大量的示例代碼,只要電腦安裝了瀏覽器,就可以用來實(shí)驗(yàn)了。讀者可以一邊讀一邊運(yùn)行示例,加深理解。
推薦安裝 Chrome 瀏覽器,它的“開發(fā)者工具”(Developer Tools)里面的“控制臺(tái)”(console),就是運(yùn)行 JavaScript 代碼的理想環(huán)境。
進(jìn)入 Chrome 瀏覽器的“控制臺(tái)”,有兩種方法。
Option + Command + J
(Mac)或者Ctrl + Shift + J
(Windows / Linux)Option + Command + I
(Mac)以及Ctrl + Shift + I
(Windows / Linux),然后選擇 Console 面板
進(jìn)入控制臺(tái)以后,就可以在提示符后輸入代碼,然后按Enter
鍵,代碼就會(huì)執(zhí)行。如果按Shift + Enter
鍵,就是代碼換行,不會(huì)觸發(fā)執(zhí)行。建議閱讀本教程時(shí),將代碼復(fù)制到控制臺(tái)進(jìn)行實(shí)驗(yàn)。
作為嘗試,你可以將下面的程序復(fù)制到“控制臺(tái)”,按下回車后,就可以看到運(yùn)行結(jié)果。
function greetMe(yourName) {
console.log('Hello ' + yourName);
}
greetMe('World')
// Hello World
更多建議: