本書(shū)介紹JavaScript語(yǔ)言和由瀏覽器與Node實(shí)現(xiàn)的JavaScript API。本書(shū)適合有一定編程經(jīng)驗(yàn)、想學(xué)習(xí)JavaScript讀者,也適合已經(jīng)在使用JavaScript但希望更深入地理解進(jìn)而真正掌握這門(mén)語(yǔ)言的程序員。
本書(shū)的目標(biāo)是全面地講解JavaScript語(yǔ)言,對(duì)JavaScript程序中可能用到的重要的客戶(hù)端API和服務(wù)器端API提供深入的介紹。本書(shū)篇幅較長(zhǎng),內(nèi)容非常詳盡,相信認(rèn)真研究本書(shū)的讀者都能獲益良多。
適讀人群 :本書(shū)適合希望學(xué)習(xí)Web編程語(yǔ)言的初、中級(jí)程序員和希望精通JavaScript的程序員閱讀。 近25年來(lái),這本“犀牛書(shū)”憑著完整的內(nèi)容、細(xì)致的講解以及海量針對(duì)性的示例而受到全球讀者的一致好評(píng)。經(jīng)過(guò)幾代前端人的口口相傳,成為了名副其實(shí)的JavaScript權(quán)威指南!
本版已經(jīng)更新到涵蓋JavaScript的2020版。書(shū)中令人深思、富有啟發(fā)性的示例隨處可見(jiàn)。
這本“犀牛書(shū)”影響著每一位前端人,一直是幾十萬(wàn)JavaScript程序員必讀的技術(shù)著作,在很多工程師心目中有著至高無(wú)上的地位。如果你由于種種原因錯(cuò)過(guò)了它之前的版本,那一定不要再錯(cuò)過(guò)這一版了!
本書(shū)介紹JavaScript語(yǔ)言和由瀏覽器與Node實(shí)現(xiàn)的JavaScript API。本書(shū)適合有一定編程經(jīng)驗(yàn)、想學(xué)習(xí)JavaScript讀者,也適合已經(jīng)在使用JavaScript但希望更深入地理解進(jìn)而真正掌握這門(mén)語(yǔ)言的程序員。
本書(shū)的目標(biāo)是全面地講解JavaScript語(yǔ)言,對(duì)JavaScript程序中可能用到的重要的客戶(hù)端API和服務(wù)器端API提供深入的介紹。本書(shū)篇幅較長(zhǎng),內(nèi)容非常詳盡,相信認(rèn)真研究本書(shū)的讀者都能獲益良多。
【譯者序】
翻譯這本“犀牛書(shū)”是我十幾年來(lái)的一個(gè)夙愿。盡管由于種種原因錯(cuò)過(guò)了原書(shū)第5版和第6版,但終于還是得償所愿。2021年是我從事技術(shù)翻譯的第十五個(gè)年頭。因此,本書(shū)也是我傾注多年經(jīng)驗(yàn)翻譯而成的。
雖然翻譯本書(shū)前前后后花了6個(gè)多月,但囿于工作和生活的壓力,我確實(shí)做不到對(duì)書(shū)中每一句話(huà)都反復(fù)推敲。我當(dāng)然知道“好譯文是改出來(lái)的”,但翻譯也是一門(mén)“遺憾的藝術(shù)”,所以我的翻譯肯定不是完美無(wú)缺的。如果要我對(duì)這本書(shū)(或者說(shuō)對(duì)我近十年來(lái)翻譯出版的所有技術(shù)專(zhuān)著,包括2020年上市的“紅寶書(shū)”第4版)的翻譯過(guò)程打個(gè)比方,我想最貼切的比喻莫過(guò)于即興視奏:面對(duì)一本從未見(jiàn)過(guò)的樂(lè)譜,你必須從奏響第一個(gè)音符開(kāi)始,一氣呵成地把整首曲子演奏完。演奏開(kāi)始后,唯一的目標(biāo)就是全神貫注,心無(wú)旁騖,快速看懂每個(gè)音符、每個(gè)節(jié)奏,盡最大努力把內(nèi)容按照原樣準(zhǔn)確無(wú)誤地呈現(xiàn)出來(lái)。當(dāng)然,不同的是,翻譯過(guò)程中雖然也有假想的讀者存在,但這些“讀者”并不妨礙我在發(fā)覺(jué)之前章節(jié)的翻譯有問(wèn)題時(shí)回過(guò)頭去修正。
這其實(shí)正是我期望的理想翻譯狀態(tài),即“一邊閱讀,一邊翻譯”。技術(shù)圖書(shū)翻譯屬于非文學(xué)翻譯或者技術(shù)翻譯的范疇。技術(shù)翻譯的主要目的是譯文準(zhǔn)確、通順,確保其當(dāng)時(shí)當(dāng)下的實(shí)用性。除此之外,對(duì)文筆或修辭的技巧無(wú)須做過(guò)高要求。一本優(yōu)秀的技術(shù)圖書(shū),最終讓讀者受益的是它的內(nèi)容和思想,而不是它的文字。文字作為形式或載體固然重要,但從譯者的角度來(lái)說(shuō),不讓自己的文字成為傳達(dá)內(nèi)容的阻礙就是最大的貢獻(xiàn);仡櫸业募夹g(shù)翻譯生涯,十幾年來(lái)從未間斷翻譯實(shí)踐。隨著翻譯經(jīng)驗(yàn)的不斷積累,我對(duì)翻譯的認(rèn)知也經(jīng)歷了深入淺出的過(guò)程。從最初的“翻譯即翻譯”,到后來(lái)的“翻譯即寫(xiě)作”,再到如今的“翻譯即閱讀”,經(jīng)歷了幾次較大的揚(yáng)棄。“翻譯”和“寫(xiě)作”,強(qiáng)調(diào)的其實(shí)是“轉(zhuǎn)換”和“表達(dá)”,而“閱讀”強(qiáng)調(diào)的則是對(duì)原文的理解。某種程度上,這可能也說(shuō)明自己已經(jīng)比較成功地解決了“轉(zhuǎn)換”和“表達(dá)”的問(wèn)題,從而可以把精力更多地放到“閱讀”和“理解”上。
JavaScript無(wú)疑是一門(mén)成功的語(yǔ)言,而且是世界上使用最多的語(yǔ)言。這本“犀牛書(shū)”在很多工程師心目中有著至高無(wú)上的地位。如果你由于種種原因錯(cuò)過(guò)了它之前的版本,那一定不要再錯(cuò)過(guò)這一版了。在我看來(lái),盡管市面上講解JavaScript語(yǔ)言和技術(shù)的專(zhuān)著層出不窮,但像這本書(shū)這樣能夠貼近ECMAScript和W3C規(guī)范的著作并不多見(jiàn)。ECMAScript和W3C規(guī)范是用英文寫(xiě)的,這對(duì)母語(yǔ)為中文的工程師無(wú)疑是個(gè)巨大的障礙。希望本書(shū)在字里行間流露出的與各種規(guī)范千絲萬(wàn)縷的聯(lián)系,能夠時(shí)刻提醒每一位讀者多花一些時(shí)間去研究語(yǔ)言本身和規(guī)范本身。這不僅僅是個(gè)“知其然,也知其所以然”的問(wèn)題,更是一個(gè)追趕和超越的問(wèn)題。相信再過(guò)5年、10年、20年,中文開(kāi)發(fā)者社區(qū)一定能夠涌現(xiàn)出更多屹立在時(shí)代潮頭的工程師和作者。
李松峰
●第1章 JavaScript簡(jiǎn)介5
1.1 探索JavaScript7
1.2 Hello World8
1.3 JavaScript之旅9
1.4 示例:字符頻率柱形圖14
1.5 小結(jié)17
●第2章 詞法結(jié)構(gòu)18
2.1 JavaScript程序的文本18
2.2 注釋19
2.3 字面量19
2.4 標(biāo)識(shí)符和保留字19
2.5 Unicode20
2.6 可選的分號(hào)21
2.7 小結(jié)23
●第3章 類(lèi)型、值和變量24
3.1 概述與定義24
3.2 數(shù)值26
3.3 文本32
3.4 布爾值38
3.5 null與undefined39
3.6 符號(hào)40
3.7 全局對(duì)象41
3.8 不可修改的原始值與可修改的對(duì)象引用42
3.9 類(lèi)型轉(zhuǎn)換44
3.10 變量聲明與賦值51
3.11 小結(jié)58
●第4章 表達(dá)式與操作符59
4.1 主表達(dá)式59
4.2 對(duì)象和數(shù)組初始化程序60
4.3 函數(shù)定義表達(dá)式61
4.4 屬性訪(fǎng)問(wèn)表達(dá)式62
4.5 調(diào)用表達(dá)式64
4.6 對(duì)象創(chuàng)建表達(dá)式65
4.7 操作符概述66
4.8 算術(shù)表達(dá)式70
4.9 關(guān)系表達(dá)式75
4.10 邏輯表達(dá)式79
4.11 賦值表達(dá)式82
4.12 求值表達(dá)式83
4.13 其他操作符86
4.14 小結(jié)91
●第5章 語(yǔ)句92
5.1 表達(dá)式語(yǔ)句93
5.2 復(fù)合語(yǔ)句與空語(yǔ)句93
5.3 條件語(yǔ)句94
5.4 循環(huán)語(yǔ)句99
5.5 跳轉(zhuǎn)語(yǔ)句106
5.6 其他語(yǔ)句113
5.7 聲明117
5.8 小結(jié)119
●第6章 對(duì)象120
6.1 對(duì)象簡(jiǎn)介120
6.2 創(chuàng)建對(duì)象121
6.3 查詢(xún)和設(shè)置屬性124
6.4 刪除屬性128
6.5 測(cè)試屬性129
6.6 枚舉屬性130
6.7 擴(kuò)展對(duì)象131
6.8 序列化對(duì)象133
6.9 對(duì)象方法133
6.10 對(duì)象字面量擴(kuò)展語(yǔ)法135
6.11 小結(jié)141
●第7章 數(shù)組143
7.1 創(chuàng)建數(shù)組144
7.2 讀寫(xiě)數(shù)組元素146
7.3 稀疏數(shù)組148
7.4 數(shù)組長(zhǎng)度148
7.5 添加和刪除數(shù)組元素149
7.6 迭代數(shù)組150
7.7 多維數(shù)組151
7.8 數(shù)組方法152
7.9 類(lèi)數(shù)組對(duì)象163
7.10 作為數(shù)組的字符串165
7.11 小結(jié)166
●第8章 函數(shù)167
8.1 定義函數(shù)167
8.2 調(diào)用函數(shù)172
8.3 函數(shù)實(shí)參與形參177
8.4 函數(shù)作為值184
8.5 函數(shù)作為命名空間187
8.6 閉包188
8.7 函數(shù)屬性、方法與構(gòu)造函數(shù)192
8.8 函數(shù)式編程196
8.9 小結(jié)201
●第9章 類(lèi)202
9.1 類(lèi)和原型203
9.2 類(lèi)和構(gòu)造函數(shù)204
9.3 使用class關(guān)鍵字的類(lèi)209
9.4 為已有類(lèi)添加方法215
9.5 子類(lèi)216
9.6 小結(jié)226
●第10章 模塊227
10.1 基于類(lèi)、對(duì)象和閉包的模塊227
10.2 Node中的模塊230
10.3 ES6中的模塊232
10.4 小結(jié)242
●第11章 JavaScript標(biāo)準(zhǔn)庫(kù)243
11.1 集合與映射244
11.2 定型數(shù)組與二進(jìn)制數(shù)據(jù)249
11.3 正則表達(dá)式與模式匹配255
11.4 日期與時(shí)間273
11.5 Error類(lèi)276
11.6 JSON序列化與解析277
11.7 國(guó)際化API280
11.8 控制臺(tái)API287
11.9 URL API290
11.10 計(jì)時(shí)器293
11.11 小結(jié)294
●第12章 迭代器與生成器295
12.1 迭代器原理296
12.2 實(shí)現(xiàn)可迭代對(duì)象296
12.3 生成器300
12.4 高級(jí)生成器特性303
12.5 小結(jié)306
●第13章 異步JavaScript307
13.1 使用回調(diào)的異步編程307
13.2 期約(Promise)311
13.3 async和await330
13.4 異步迭代332
13.5 小結(jié)338
●第14章 元編程340
14.1 屬性的特性340
14.2 對(duì)象的可擴(kuò)展能力345
14.3 prototype特性346
14.4 公認(rèn)符號(hào)347
14.5 模板標(biāo)簽354
14.6 反射API356
14.7 代理對(duì)象359
14.8 小結(jié)365
●第15章 瀏覽器中的JavaScript367
15.1 Web編程基礎(chǔ)369
15.2 事件382
15.3 操作DOM391
15.4 操作CSS406
15.5 文檔幾何與滾動(dòng)412
15.6 Web組件416
15.7 可伸縮矢量圖形427
15.8 < canvas > 與圖形434
15.9 Audio API453
15.10 位置、導(dǎo)航與歷史455
15.11 網(wǎng)絡(luò)463
15.12 存儲(chǔ)479
15.13 工作線(xiàn)程與消息傳遞490
15.14 示例:曼德布洛特集合496
15.15 小結(jié)及未來(lái)閱讀建議508
●第16章 Node服務(wù)器端JavaScript515
16.1 Node編程基礎(chǔ)516
16.2 Node默認(rèn)異步520
16.3 緩沖區(qū)523
16.4 事件與EventEmitter525
16.5 流526
16.6 進(jìn)程、CPU和操作系統(tǒng)細(xì)節(jié)536
16.7 操作文件537
16.8 HTTP客戶(hù)端與服務(wù)器547
16.9 非HTTP網(wǎng)絡(luò)服務(wù)器及客戶(hù)端551
16.10 操作子進(jìn)程554
16.11 工作線(xiàn)程558
16.12 小結(jié)566
●第17章 JavaScript工具和擴(kuò)展568
17.1 使用ESLint檢查代碼569
17.2 使用Prettier格式化代碼570
17.3 使用Jest做單元測(cè)試570
17.4 使用npm管理依賴(lài)包573
17.5 代碼打包574
17.6 使用Babel轉(zhuǎn)譯576
17.7 JSX:JavaScript中的標(biāo)記表達(dá)式577
17.8 使用Flow檢查類(lèi)型581
17.9 小結(jié)595