JavaScript:世紀機器語言?

cwf8 9年前發布 | 46K 次閱讀 JavaScript

原文</i>  http://mp.weixin.qq.com/s?__biz=MzA3NDM0ODQwMw==&mid=206520119&idx=1&sn=2631fea1aedada919e56383584f98070 </span>


在我寫了「顛覆者的游戲 - 程序語言」和「elixir - 靈丹妙藥?or 徒有其名?」后,就有同學就讓我講講javascript。對于這門讓人又愛又恨的語言,真要講,我都不知道怎么開頭了。套用『北京人在紐約』里的臺詞: 「如果你愛TA,請讓TA用Javascript,做為一個程序員,TA此生無憂;如果你恨TA,請讓TA用Javascript,做為一個程序員,TA 基本毀了」。

無所不在的javascript

說Javascript程序員此生無憂有很多理由,最大的理由就是:web無處不在,有web存在的地方,就有javascript存在的地方,所以 javascript程序員是皇上的女兒不愁嫁。一個好的javascript程序員,他的痛苦是:這么多工作機會,到底哪個是Sandberg說的 rocket ship? [1]

javascript在web frontend的統治地位是毋庸置疑的。不像backend那么多千奇百怪的選擇,在frontend,二十年來大浪淘沙,有且只有一門能在任何瀏覽器中運行的語言:javascript。而自 prototypescript.aculo.us 開啟了小團隊的web2.0之旅后,javascript的生態圈呈爆炸性的繁榮。

web backend不必多說,nodejs已經火熱了幾年,早年的流行詞LAMP [2] 都換成了MEAN [3] 這樣的full stack js framework。這讓很多前端工程師努努力就變成了全棧,一下子轉扶搖而上,沖到了鄙視鏈的上層。

在mobile frontend上,cordova,ionic等html5 mobile app framework在不斷努力讓生活在WebView下的基于javascript的hybrid mobile app能夠達到接近native app的表現。作為移動領域的頭牌,apple對javascript也是又愛又恨 —— 愛其繁榮的生態圈,快速產品化的能力 [4] ,恨其一次編寫到處運行的優勢,無奈這股浪潮已經勢不可當,于是在iOS 8里,apple終于在面對WebView也提供了早就在safari中提供的Nitro JIT engine。我倒不是說hybrid mobile app完全會取代native app,目前還不具備這個可能,但很多應用場景,hybrid app已經能夠很好勝任。

桌面系統的領地,被node-webkit,atom-shell等一大票基于CEF [5] 的chrome衍生品也攻克了。CEF的理念很簡單:每個app就是一個退化的chrome(可以簡單認為把沙箱的限制取消了),跑開發者定制的 html/css/javascript。由于chrome是跨平臺的,所以這樣的軟件也跨平臺,而且界面和web一樣,可以無比豐富(也可無比貼近本地 應用)。

硬件開發?有的是創業公司,比如tessel,看中了javascript在程序員群體的可達性,嘗試提供基于javascript的SDK,來直接操縱硬件。也許有一天,FPGA的邏輯可以用javascript來描述。

設計拙劣的javascript

作為一門語言,javascript是一俊遮百丑的典范。隨便試幾例: [6]

JavaScript:世紀機器語言? 如果你的另一半如此捉摸不定,是不是很想抽丫一大耳光,轉身離去?可惜這也就止于意淫 —— 誰讓人家顏值太高,小性子壞脾氣再多,你也得忍著,對么?

javascript是可能現代編程語言中設計周期最短的,據說Brendan Eich只有10天時間來設計它,基本思路是他自己的背景(函數式編程)和網景/Sun的背景(Java和面向對象編程)的大雜燴 [7]

(1) C的基本語法

(2) Java的數據類型和內存管理

(3) Scheme的函數能力(函數是一等公民)

(4) Self的 prototype 的繼承機制

和其它深思熟慮設計出來的語言(比如說clojure [8] ),javascript就是一個災難。而更大的災難是:原本只是在瀏覽器里跑一跑,對DOM進行簡單操作,響應DOM事件,讓靜止的網頁能夠和用戶有更 多交互性的一門表達能力并不很強的,從來沒想過單個應用會超過上千行代碼(所以javascript連最基本的module都沒提供)的語言,慢慢地成了 世間萬物(web)的主宰!

javascript程序員的撕扯人生

這真是件撕扯的事情。一方面語言有不少弱點,另一方面你又需要用這種語言去完成越來越多的事情。

比如說讓人又愛又恨的 this 。有好幾種不同的 scope 或者 context 會使用 this ,在層層嵌套的函數里,多少人用起來戰戰兢兢?

還有基于prototype的繼承,有多少人真正研究一下prototype的概念,以及這么處理繼承和其他主流面向對象語言的異同?優劣?

我們知道在學習一門新的語言時,大家往往會進行比較嚴格的語言訓練,否則想把代碼寫正確并且寫漂亮很難。但javascript不同,似乎沒有人 特別認真對待它,很多前端工程師或者后端工程師幾乎就是翻一兩個教程,因項目需要,順帶著把自己的語言能力擴展到javascript,根本沒有系統學 習,所以 —— 不得不直面各種各樣的慘淡人生。

要getting things right,你需要了解其good part,避免其缺陷或者容易跑偏的部分。

JavaScript:世紀機器語言? (這圖寓意深刻啊~)

救星:compile to javascript

擺脫這種困境最直接的方法是靜下心來好好學習javascript,取其精華,去其糟粕。遺憾的是,這并不如想象的那樣簡單。有人看到了其中的機 會:既然javascript不可替換,那何不發明(利用)一門語言,將其編譯成javascript呢?就像C語言被編譯成機器指令,或者java被編 譯成byte code?

JavaScript:世紀機器語言? (準機器代碼)

JavaScript:世紀機器語言?

(web世界的準機器代碼)

于是,compile to javascript的語言便如雨后春筍般漲了出來。它們大致可以分三類:

1) 新語言,取javascript的子集(good parts)。如asm.js [9] ,coffeescript。coffeescript用更好更簡潔的語法撰寫代碼,編譯出來的javascript比較優美。使用起來毫無壓力,大愛 ? 和其函數式編程的風格。

2) 新語言,在javascript語言基礎上擴展。如typescript。javascript的超集。沒用過。

3) 已有語言的子集,能編譯出javascript的子集。如coffeescript,gopher2js。

點擊「閱讀原文」可以看到完整的compile to javascript的清單。

編譯這事,并不簡單,嚴復說譯事三難:「信,達,雅」。這三點對應于編譯就是:

1) 準確無誤。不能歪曲了程序員的意思。

2) 不拘泥于原文,盡可能優化。在這里就是minify的能力要到位。

3) 編譯結果越小越好。在這里就是dead code elimination。

你看一個標準的gcc編譯器,這三點在不同的 -O 選項下,都能做到 [10] 。而在compile to javascript領域里,做到(好) 2)與3)的很少。minify應該是編譯時的動作,很多語言(比如coffeescript)都忽略它,而是使用各種現成的uglifier在編譯后進行。少了AST [11] 層面的支持,很多minify的事情都做不了。

dead code elimination更是如此,一個jQuery的Lib你可能就用到了dom operation,那各種animation的代碼就是dead code。90%以上的語言在這個領域毫無作為。

這里要專門贊一下clojurescript,這三者它都做得很好,而且很美。clojurescript在設計之初,就把google closure compiler作為其編譯基礎。google closure compiler在優化javascript時的瘋狂,堪比gcc的 -O3 。它在做到「信」的基礎上,最大程度地壓縮你的代碼,不僅刪除所有不在執行路徑上的代碼,還把你的函數各種inline。當然,這是有代價的:你需要滿足 特定的約束,寫能讓closure compiler優化的代碼 —— 這幾乎不是正常人干的事情。所以clojurescript就替你完成這件事:你用clojure(的子集)寫代碼,它幫你生成滿足closure script約束的javascript。

在小型項目上,compile to javascript的優勢并不明顯,但項目越大,系統越復雜,這種優勢就越明顯。atom是coffeescript寫的,lighttable是 clojurescript寫的。我相信,隨著這些compile to javascript的項目本身的逐漸成熟,以及其生態圈的逐漸完善,越來越多的復雜系統,會不再使用手寫的javascript,轉而使用表達能力更強 的語言。

如果您覺得這篇文章不錯,請點贊。多謝!

歡迎訂閱公眾號『程序人生』(搜索微信號 programmer_life)。每篇文章都力求原汁原味,北京時間中午12點左右,美西時間下午8點左右與您相會。

1. If you’re offered a seat on a rocket ship, don’t ask what seat. Just get on.

2. linux, apache, mysql, php

3. mongodb, express, angular, nodejs

4. 意味著單位時間能產生更多的app

5. Chromium Embedded Framework

6. 更多可以參見阮一峰的javascript 10個設計缺陷:http://www.ruanyifeng.com/blog/2011/06/10_design_defects_in_javascript.html

7. 見阮一峰的Javascript誕生記:http://www.ruanyifeng.com/blog/2011/06/birth_of_javascript.html

8. 簡直和javascript是兩個極端

9. 這個有空單獨撰文描述

10. 函數inline,指令優化,刪除無調用函數等

11. Abstract Syntax Tree

 本文由用戶 cwf8 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!