作者: 李松峰
轉發鏈接:https://mp.weixin.qq.com/s/guAN1Cz2gYfKdBhmUpLyVA
前言
JAVAScript這門語言的第一個演示版差不多就在25年前誕生。
沒記錯的話,25年前的今天,1995年5月10日,星期三,我剛剛過了創造JavaScript(代號為“Mocha”)的“5月的10天”沖刺的一半。我正在寫下個周一就要交付的一個演示,目的是展示JS與Netscape的深度瀏覽器集成(相對于Java小應用)。
1995年秋天,這門語言在Netscape Navigator的一個測試版中發布,當時叫LiveScript。那一年的年底,又被改名為JavaScript。也是在那一年,David Flanagan開始寫JavaScript: The Definitive Guide的第一版,并由O'Reilly在1996年8月出版。如今,24年過去了。
犀牛書(英文版)第7版再過幾個星期就要面世了。為此,David回憶了一下,想告訴大家有哪些JavaScript特性可以放心地忘掉。一個原因是第七版比第6版薄了不少。而這主要是因為之前的很多東西2020年的開發者已經不用關心了。Web兼容性永遠存在(至少25年以來一直如此),瀏覽器廠商可能在很長時期內仍然需要支持那些陳舊的、難以理解的語言和平臺特性。但對我們而言,已經沒有必要再為這些特性分心了。
也就是說,有不少JavaScript和Web平臺特性在第7版里已經銷聲匿跡了。應該說,能對這些特性說再見是件高興的事。以下就是David憑記憶列出的幾個應該忘記的特性。
arguments對象
arguments對象已經被ES6的...args語法完全取代。要解釋清楚arguments與命名參數的關系,以及始終注意它對性能的影響著實不易。在遺留的前端代碼中,也許還會看到它的身影。在嚴格模式下如果想將局部變量或函數參數命名為arguments,那瀏覽器也會提醒你它的存在。不過現在有了剩余參數,它就應該悄悄地被人遺忘了。
拼接字符串
曾幾何時,我們還會擔心重復拼接字符串導致的性能問題。有一段時間,大家都學會了先把字符串推到數組里,最后再使用join()把它們拼接起來。后來,JavaScript變快了,我們就把這個模式給忘了。而現在有了模板字面量,誰還會再拼接字符串呢?
document.write()
document.write()在很早以前,確切地說是在DOM問世之前,曾經是JavaScript中最重要的特性。(如果你沒在20世紀寫過JavaScript,那可能想象不到DOM出現之前的日子,但那個時代真的存在過。)如果沒記錯的話,人們甚至可以使用document.write()向文檔中插入腳本。不過這時候要小心,因為你得把末尾的</script>標簽拆成兩個字符串。這樣html解析器才不會把它解釋為當前運行腳本的結束標簽。
frame 相關
HTML早期是沒有<iframe>的,不過有<frameset>和<frame>。window.frames屬性是一個數組,包含嵌套的window對象,表示文檔中的窗格。實際上,可以在窗格中調用文檔的open()方法,然后使用document.write()在該窗格中動態生成整個文檔。不管怎么說,這還真有點酷。因為窗格可以嵌套在其他窗格中,每個window對象都有一個frames數組包含自己的子窗格、一個parent屬性引用包含窗口和一個top屬性引用頂級窗口。犀牛書的早期版本專門用了幾節篇幅和復雜的示意圖來解釋這些內容。
直接引用特定元素相關
在文檔中直接引用特定元素的技術基本上都廢棄了。前面說到的frames數組是一個,沒記錯的話,還有links和images數組,包含文檔中的所有鏈接和所有圖片。IE(我記得應該是版本4)一步到位,引入了document.all,這是一個包含文檔中所有元素的數組。(這也是“DHTML”也就是“動態HTML”及后來DOM的發端,有點像人類進化史上第一條爬上陸地的魚。)document.all有各種各樣新奇的特性,它這個數組本身還有很多按名字或按其他條件來查詢元素的方法。document.all最終沒有被寫進標準,但即便是標準的document.getElementById()、document.getElementsByName()、document.getElementsByTagName()和docuemnt.getElementsByClassName()方法,在今天看來似乎也已經沒多少人用了。因為受到了jQuery的$()及受它啟發而引入標準的document.querySelector()和document.querySelectorAll()的排擠。借用css選擇符的威力,這兩個方法直接就把之前的那些方法都給廢掉了。
事件及其處理程序兼容
說起我最恨Internet Explorer的一件事,就是他們非要使用attachEvent()來注冊事件處理程序。在我的印象中,他們是在標準已經規定了addEventListener()方法之后這么搞的,這可真是太討厭了。事件及其處理程序一直以來都是Web開發中一個最大的不兼容問題。多少年以來,JavaScript程序員(和JavaScript圖書作者)都必須處理IE事件模型與標準事件模型的各種差異。為此,處理事件的代碼必須寫兩遍,一遍針對IE,一遍針對Firefox。書中介紹事件的章節相應地也會兩倍長,因為有兩套非常相似但卻完全不兼容的事件處理機制。jQuery的一個主要特性就是實現了自己的事件兼容層,于是開發者只需掌握一種事件處理方式即可。我懷疑這也是它快速流行的一個重要原因。
DOM API 相關
最初的DOM API是在人們瘋狂迷戀XML的時代定義的。(當時的人們確實相信用不了幾年,XML就可以解決所有數據問題。真是個難以置信的時代。)某種程度上,正是W3C的認可,才讓Java那些人影響了DOM API,這些人覺得最好只定義一套API,JavaScript程序員能用它操作HTML文檔,而Java程序員能用它操作XML數據。這也是為什么會有Attr節點(最好當它不存在)這么怪異的東西的原因。DOM Level 3 API中最讓我不理解的一個操作是從文檔中刪除元素e,你不能像今天這樣寫成e.remove(),而是必須寫成e.parentNode.removeChild(e)。
不管怎么說,現在都已經2020年了。犀牛書第7版將不會再花筆墨描述這些陳舊的特性,這些特性大家最好還是忘掉。