【為什麼我們挑選這篇文章】程式語言不計其數,每年都在推陳出新,也許今天一半以上的語言你都了解,但過了兩三年你知道的語言可能已經過時了也說不定。
內文透過一來一往的對答,讓我們知道程式語言的多樣、複雜性,而現在,是時候來考考你看不看得懂他們的對話了!(責任編輯:張瑋倫)
作者/Jose Aguinaga,譯者/方應杭
嘿,我最近接到一個 Web 項目,不過老實說,我這兩年沒怎麼接觸 Web 編程語言,聽說 Web 技術已經發生了一些變化。聽說你是這裡對新技術最了解的 Web 開發工程師?
準確地說,我是一名「前端工程師」。不過你算是找對人了。我對今年的技術別提多熟了,前端可視化、音樂播放器、能踢足球的無人機,你儘管問吧。
我剛去 JS 大會和 React 大會逛了一圈,沒有什麼新技術是我不知道的。
厲害。是這樣的,我要開發一個網頁,用來展示用戶的最新動態。我想我應該通過後端接口獲取數據,然後用一個 table 來展示數據,用戶可以對數據進行排序。如果伺服器上的數據變化了,我還需要更新這個 table。我的思路是用 jQuery 來做。
可別用 jQuery!現在哪還有人用 jQuery。現在是 2016 年了,你絕對應該用 React。
哦,好吧,React 是什麼?
React 是一個非常厲害的資料庫,Facebook 的牛人寫的。它能讓頁面更可控,性能極高,而且使用起來很簡單。
聽起來確實不錯。我能用 React 展示伺服器傳來的數據嗎?
當然可以,你只需要添加兩個依賴,一個是 React,一個是 React DOM
額,等下,為什麼是兩個資料庫?
React 是我說的資料庫,React DOM 是用來操作 DOM 的。因為這些 DOM 是用 JSX 寫的,所以需要一個專門的資料庫來操作。
JSX?JSX 是什麼?
JSX 是對 JS 的擴展,它看起來跟 XML 差不多,可以用來寫 HTML,你可以認為 JSX 是一種更優雅的 HTML 寫法。
為什麼不用 HTML 了……?
現在可是 2016 年啊,沒有直接寫 HTML 的。
對哦。好吧,加了這兩個依賴,是不是就可以開始用 React 了?
不行哦。你需要添加 Babel,然後才能用 React。
Babel 是另一個資料庫?
嗯,Babel 是一個轉譯工具,Babel 能把你寫的 JS 轉譯成任意版本的 JS。你不一定非要用 Babel,但是如果你不用的話,你就只能寫 ES5 的語法了。
你知道的,現在是 2016 年,你怎麼能不使用 ES2016+ 的語法呢?ES2016+ 多麼酷啊。
ES5 是什麼?ES2016+ 又是什麼?我有點暈。
ES5 就是 ECMAScript 5。大部分人都會使用 ES5,因為大部分瀏覽器都支持 ES5。
ECMAScript 是什麼……
你曉得的,JS 是1995年誕生的,而 JS 的標準是1999制定出來的。那時候 JavaScript 還叫做 Livescript,只能運行在網景的瀏覽器裡。那時真是混亂的年代,現在好了,我們有了 JS 的 7 個版本的規範。
7 個版本?那 ES5 和 ES2016+ 是?
分別是第 5 個版本和第 7 個版本。
誒,那第六個版本呢?
你說的是 ES6。每個版本都是上一個版本的超集,所以你直接使用最新的 ES2016+ 就好了。
對哦。為什麼不用 ES6 呢?
好吧,你可以用 ES6,但是你就用不到 async 和 await 這麼酷的語法了。用 ES2016+ 比較好。用 ES6 的話你就只能用 generator 來控制異步任務流了。
不知道你在說什麼……你說了太多我聽不懂的名詞了。我只是想從伺服器取點數據,我以前用 jQuery 挺好的,從 CDN 引入 jQuery,我就能用 AJAX 獲取數據了,現在不能這樣做嗎?
大哥,都 2016 年了,沒人用 jQuery 好嗎。所有人都知道用 jQuery 只會造出「意大利麵條」一樣的代碼(不可維護)
好吧,所以我現在要加載三個資料庫才能獲取並展示數據。
對的,其實你可以用「模塊管理器」把這三個資料庫「打包」成一個文件。
哦,什麼是模塊管理器……
不同平台的模塊管理器不同啦。前端的模塊管理器一般指管理 AMD 或者 CommonJS 模塊的東西。
好……吧,什麼是 AMD 和 CommonJS?
是兩個定義。我們有很多方式來描述 JS 中多個資料庫或類的交互方式,比如 exports 和 requires。你可以按照 AMD 或者 CommonJS 的 API 來書寫 JS,然後用 Browserify 將它們打包。
聽起來很有道理。不過,什麼是 Browserify?
是一個工具,用來將 CommonJS 形式的 JS 文件打包起來,放到瀏覽器裡運行。用 npm 倉資料庫的人發明了 CommonJS。
npm 倉資料庫是什麼……
是一個公開的倉庫,用於放置可依賴的模塊。
就像一個 CDN 麼?
不太一樣。它更像是一個資料資料庫,每個人都能在上面發布代碼,也能下載上面的代碼。你可以在開發的時候將這些代碼下載到本地來使用,必要的時候也能上傳到 CDN。
聽起來像是 Bower!
是的,不過現在是 2016 年了,沒有人用 Bower 了……
好吧,我知道了,所以我應該用 npm 來安裝依賴。
對的。我舉個例子吧,如果你要使用 React,你直接用 npm 安裝 React,然後在代碼裡導入 React 就可以了。大部分 JS 資料庫都能這麼安裝。
嗯,Angular 也可以。
Angular 是 2015 年的事情了。不過今年 Angular 還沒死,還有 VueJS 和 RxJS 等等,你想學一學麼?
還是用 React 吧。我剛才已經學了夠多東西了。所以我用 npm 安裝 React 然後用 Browerify 來打包就好了?
是的。
這麼做看起來有點過於複雜啊。
確實。這就是為什麼你應該使用 Grunt、Gulp 或者 Broccoli 這樣的任務管理工具,它們能自動運行 Browserify。不對,你現在可以用 Mimosa。
你在說什麼……
任務管理工具。不過我們現在已經不用了。去年我們還在用,後來改成了 Makefiles,但是現在我們用的都是 Webpack。
我以為只有 C/C++ 項目才會用 Makefiles。
是的,不過顯然我們做 Web 開發的,喜歡先把事情搞複雜,然後回歸到最樸素的狀態。每年我們都是這麼搞的。你就看著吧,過不了兩年,我們就可以在網頁上寫彙編了。
唉,你剛才說的 Webpack 是什麼?
另一種模塊管理工具,同時也是一個任務管理工具。你可以認為它是 Browserify 的加強版。
哦,好吧,為什麼 Webpack 是加強版?
額,可能並沒有加強吧。Webpack 告訴你應該如何管理你的依賴,Webpack 允許你使用不同的模塊管理器,不只是 CommonJS,甚至支持 ES6 模塊。
這都是哪跟哪啊,我都被繞暈了。
大家都被繞暈了,不過等 SystemJS 出來了就好了。
天吶,又一個 JS 資料庫,這是什麼鬼?
呵呵,不像 Browserify 和 Webpack 1.x,SystemJS 是一個動態的模塊加載器。
等下,剛才不是說應該把所有依賴打包成一個文件嗎?
話是這麼說,但是等 HTTP/2 普及之後,不打包反而更好。
那為什麼我們不直接在頁面裡添加 React 的三個依賴文件呢?
不行。你可以從 CDN 加載這些文件,但是你還是要在本地用 Babel 轉譯。
唉,這麼鹺?
是的,你不能在生產環境上運行 babel,你應該在發布到生產環境之前,運行一系列的任務,包括壓縮、混淆、內聯化CSS、延遲加載script……
我懂了我懂了。既然我不能直接用 CDN,那麼我應該怎麼做?
我會考慮用 Webpack + SystemJS + Babel 來轉譯 Typescript。
Typescript?我們不是在說 JavaScript 嗎?!
Typescript 也是 JavaScript 呀,它比 JS 更好用,是 JS 的超集,它是基於 ES6 的,就是我們剛才談論的 ES6,你還記得吧。
ES2016+ 已經是 ES6 的超集了,怎麼又冒出來一個 Typescript?
是這樣的,Typescript 能讓我們寫出「強類型」的 JS,從而減少運行時的錯誤。2016年,我們應該讓 JS 支持強類型了。
顯然 Typescript 可以做到。
Flow 也可以做到,區別是 Typescript 需要編譯,而 Flow 只是檢查語法。
唉,Flow 是?
是一個靜態類型檢查器,就是 Facebook 的人寫的。使用 OCaml 寫的,函數式編程很叼的。
OCaml?函數式編程?
如今大牛都用這些東西,都 2016年了,你懂的,函數式編程、高階函數、柯裡化、純函數這些概念。
不知道你在說什麼。
一開始大家都不知道。這麼說吧,你只需要知道函數式編程語言比物件導向程式設計厲害,2016 年我們就指著函數式編程了。
等下,我大學裡學過物件導向程式設計,當時我覺得它還不錯。
Java 在被 Oracle 買下來之前也挺不錯啊。我的意思是,面向對象以前是不錯,現在依然有人用它,但是現在所有人都發覺狀態變換是很難維護的,所以大家都開始用「不可變對象」和函數式編程了。
Haskell 的人已經用這套東西用了很久了,不過幸運的是 Web 開發領域裡有 Ramda 這樣的資料庫,讓我們用 JS 就可以進行函數式編程了。
你剛剛是不是又拋出了幾個名詞?Ramnda 又是什麼?
不是 Ramnda,是 Ramda,跟 Lambda 表達式有點像。是 David Chambers 寫的資料庫。
誰?
David Chambers,大神一個。blablabla
我不得不打斷你一下了。這些東西看起來都不錯,但是我覺得它們都太複雜,而且沒必要。我只是想獲取數據然後展示,我很確定這種情況下我不需要掌握這些知識。
回到 React 吧,用 React 我怎麼從伺服器獲取數據?
額,React 沒有提供這個功能,你只能用 React 展示數據。
服了啊。那我怎麼獲取數據?
你用 Fetch API 就可以了。
什麼玩意?這個 API 的名字很爛啊。
我也覺得是啊。Fetch API 是瀏覽器提供的異步請求接口。
哦,那不就是 AJAX。
AJAX 只是使用 XMLHttpRequest 對象,但是 Fetch API 可以讓你用 Promise 風格來發起異步請求,幫你擺脫「回調地獄」。
回調地獄?
是的,每次你發起一個異步請求,就得等待它響應。這時你就得在函數裡使用一個函數,這種嵌套調用就是回調地獄。
好吧。Promise 解決了這個問題麼?
是的。用 Promise 來管理回調,你就可以寫出更易讀的代碼,更容易測試的代碼。甚至可以同時發起多個請求,然後等待它們全部返回。
Fetch 也能做到嗎?
是的。但前提是你的用戶使用了新版的瀏覽器,不然的話你就需要加一個 Fetch 的 「polyfill」,或者使用 Request、Bluebird 或者 Axios 這些資料庫。
天啊我到底需要多少個資料庫?
這是 JS,同一件事情有上千個資料庫在做。我們了解資料庫,而且我們有最好的資料庫,我們有海量的資料庫,要什麼有什麼。
你剛才說的幾個資料庫都是幹什麼的?
這幾個資料庫操作 XMLHttpRequest 然後返回 Promise 對象。
好像 jQuery 的 ajax 方法做的是同樣的事吧……
從 2016 年起我們就不用 jQuery 了。用 Fetch,大不了加個 Polyfill,要不然用 Bluebird、Request 或者 Axios 都行。然後用 await 和 async 管理 Promise,這樣才能控制好異步任務。
這是你第三次說 await 了,那是什麼東西?
await 能讓你攔住一個異步調用,讓你更好地控制異步返回的數據,大大增強了代碼的可讀性。await 非常好用,你只需要在 Babel 裡添加 stage–3 配置,或者添加 syntax-async-functions 和 transform-async-to-generator 插件就可以了。
聽起來像是瘋了。
沒瘋。為了使用 await,把 Typescript 編譯之後再用 Babel 轉譯一道的人才是瘋了。
什麼玩意?Typescript 不支持 await?
下個版本就支持了。
我已經無話可說了。
你看其實很簡單。用 Typescript 寫代碼,用 Fetch 發起異步請求,所有代碼編譯成 ES6,然後用上 Babel 的 stage–3 配置項,把 ES6 轉譯成 ES5。
所有代碼用 SystemJS 加載。如果你用不了 Fetch,就加個 polyfill,或者用 Bluebird、Request 或者 Axios,這樣你就可以用 await 來處理 Promise 了。
看了我們對於「簡單」的理解是不同的。好吧,有了這些,我終於可以獲取數據然後用 React 展示數據了,對吧?
你的網頁需要處理狀態變更嗎?
唔,不用吧。我只是想展示數據。
那就好,不然我就得跟你解釋 Flux,以及 Flux 的一些實現,比如 Flummox、Alt、Fluxible。不過說真的你應該用 Redux。
你說的這些我就當耳邊風了。再說一次,我只想展示數據。
這樣啊,如果你只是想展示數據,其實你不需要 React。你只需要一個模板引擎。
你逗我呢?
我只是告訴你你可以用什麼技術。
別說了,真的。
我想說,即使只是用一個模板引擎,我還是會用 Typescript + SystemJS + Babel 的。
我只是想在頁面上展示數據,你就告訴我用哪個模板引擎就好了。
有很多,你用過哪一個?
額,太久沒用了,不記得了。
jTemplates、jQote 還是 PURE?
額,不記得,還有別的麼?
Transparency? JSRender? MarkupJS? KnockoutJS? 這一個支持雙向綁定。
還有嗎?
PlatesJS? jQuery-tmpl? Handlebars? 還有些人在用。
有點像。有哪些跟最後一個比較像的?
Mustache, underscore? 我記得連 Lodash 都有一個模板引擎,不過這是 2014 年的事情了。
額,也許是再新一點的資料庫?
Jade? DustJS?
沒用過
DotJS? EJS?
沒用過。
Nunjucks? ECT?
沒用過。記不起來了,要是你的話,你用哪個?
我應該會用 ES6 原生的模板字符串
我猜猜,只有 ES6 支持。
對的。
需要用 Babel
對的。
需要用 npm 安裝
對的。
需要用 Browserify 或者 Webpack,或者 SystemJS
對的。
如果沒用 Webpack 的話,我還需要一個任務管理工具。
對的。
但是由於我要用函數式編程和強類型語言,所以我首先要用上 Typescript 或者 Flow。
對的。
如果我要用 await,那我就必須用 Babel 轉譯。
對的。
然後我就能用上 Fetch、Promise 和各種炫酷的東西。
嗯,別忘了加上 Fetch 的 Polyfill,因為 Safari 不支持 Fetch。
你猜怎麼著,我們就聊到這吧。我不做了,我不做 Web 了,我也不想再碰 JS 了。
沒事,過不了幾年,我們都會用 Elm 或者 WebAssembly 了。
我要回後端去了,我受不這些變動、版本更新、編譯和轉譯了,JS 社區如果覺得有人能跟上它的腳步,那這個社區就是瘋了。
我理解你。我建議你去 Python 社區。
為什麼?
聽說過 Python 3 嗎?
完。
(本文經 kknews 授權轉載,並同意 TechOrange 編寫導讀與修訂標題,原文標題為〈在 2016 年學 JavaScript 是一種什麼樣的體驗〉。圖片來源:yaph , CC Licensed,未經授權請勿轉載)
延伸閱讀
2016最紅程式語言:JavaScript,但最賺錢的不是它
JavaScript傳奇:從跑龍套到挑大樑的程式語言
IEEE Spectrum 公佈程式語言最新排行:還不跟娘子一起出來學大數據?
程式語言百百種,只想賺錢的話該選哪一種?
Python 不是大蟒蛇、Java 就是一杯咖啡,程式語言都是如何命名的?
懂越多程式語言越威嗎?一位工程師對自己職涯路上的省思
加入 TechOrange 粉絲團,產業趨勢、精闢觀點都不漏拍。