[譯]JSX:硬幣的另外一面

React框架剛剛發佈的時候,JSX顛覆了不少人的想法。習慣了HTML標籤與JavaScript代碼分離的前端工程師們,看到JSX大概都會不由吐槽:「這些奇怪的標籤出如今JavaScript裏是要幹啥?!」咱們一貫貫徹的關注點分離原則呢?Facebook的工程師難道一點都不瞭解這些社區中已經默認的規範?前端

像不少人同樣,我一開始對JSX這種語法是持懷疑態度的。甚至當我愛上JSX後,每次我向別的開發者推薦這種語法,我都會以爲我是在向別人展現我醜陋的孩子。react

從一開始的懷疑到愛上JSX,我漸漸意識到JSX其實並無那麼激進。它不過是硬幣的另外一面。JSX實際上是前端開發中天然進化的一個過渡。爲何這麼說呢,咱們有必要回顧一下前端這幾年的發展歷程了。數組

第一階段:非侵入式JavaScript(Unobtrusive JavaScript)

還記得那個jQuery盛行的時代麼?非侵入式的JavaScript被各類提倡。咱們的HTML是純HTML,咱們的JavaScript是純JavaScript。咱們開發時是嚴格貫徹所謂的關注點分離的。前端工程師

咱們像下面這樣寫HTML:框架

<a class="hide">Click to hide me</a>

而咱們的JavaScript會這樣寫:ide

$(".hide").click(function() { 
    $(this).hide(); 
})

按照以前的理解,這樣作是真的作到了關注點分離對吧?然而我以爲並非這樣。函數

這樣寫看起來像是一個好主意。咱們的HTML是絕對純淨的,徹底不參合任何邏輯代碼。可是咱們會慢慢發現一個問題:我怎麼知道哪行JavaScript代碼在控制個人HTML呢?答案是:除非我閱讀了整個JavaScript文件,我才能明白,哪段JavaScript代碼在控制哪段HTML。(譯者注:這樣的狀況很常見,尤爲是在大型項目中,咱們有無數的還有可能重複的DOM節點,HTML和JavaScript文件不在一塊兒,要修改起來簡直太複雜了)。在這種模式中,你不能僅僅簡單的修改一個標籤而不去檢查對應的JavaScript代碼以確保你的修改沒有破換選擇器執行。你看,這裏實際上並無實現關注點分離,咱們仍是要不斷的關注HTML和JavaScript之間的聯繫。咱們作到的僅僅是把JS和HTML分離到了兩個不一樣的文件中。在本質上這兩種技術是密不可分的,他們必須保持步調一致,不然就會致使咱們的應用崩潰。oop

直接分割HTML和JS致使咱們的應用更加難以維護和調試。每次你想修改一個標籤,老是會擔憂破壞一個jQuery選擇器。若是咱們對關注點的分離不那麼嚴格,也許能夠減輕一些痛苦。因而,咱們迎來了第二階段...學習

第二階段:雙向綁定(Two-way Binding)

在Knockout和Angular中出現的雙向綁定,讓全部前端開發者眼前一亮。許多開發者開始拋棄以前信奉的關注點分離,並全力擁抱這種在HTML標籤中聲明式綁定的力量。當數據發生改變,UI也自動發生變更。當UI發生變更,數據也隨之變更。如此清晰,如此簡單。(譯者注:我認爲這是另外一種意義上的關注點分離,咱們再也不須要關注HTML與JavaScript之間的聯繫,咱們須要作的就是維護好數據。)ui

這些框架的實現的確大不相同,但他們都在試圖作相同的事情。試想使用這幾個流行框架實現迭代數組這個例子:

//Angular
<div ng-repeat=」user in users」>
//Ember
{{#each user in users}}
//Knockout
data-bind=」foreach: users」

可是這裏出現了一些有意思的事情————不多有人意識到一個很是顯著的問題:咱們實際上在把JavaScript放到HTML中。這並非咱們所理解的那種關注點分離。咱們能夠發現這些框架都在處理同一件事:經過爲HTML添加額外的特殊標記使其更強大。這些標記能夠被解析爲JavaScript。所以,既然咱們可以接受JavaScript與HTML經過這種方式混合在一起,那麼是時候讓React介入並向咱們展現硬幣的另外一面了...

第三階段:JSX

React的JSX並非一個激進的改變,是由於咱們這個行業從一開始就註定HTML和JavaScript應該是在一塊兒的。

只有當你體驗過React和JSX以後,才能體會到這樣作有多少好處。React的JSX徹底優於全部的「第二階段」風格的框架的緣由有如下幾點:

編譯時錯誤(Compile-time Errors)

當你的HTML中出現輸入錯誤時,你很難知道本身是哪裏寫錯了。在不少狀況下這是一種無聲的運行時錯誤。好比,若是你在寫Angular應用時輸入n-repeat而不是ng-repeat,什麼都不會發生。當你在寫Knockout應用時把data-bind寫成data-bnd,也一樣什麼都不會發生。在出現這些錯誤時,你的應用會悄無聲息的運行時失敗。這太使人沮喪了。

相比之下,當你在JSX中發生相似的輸入錯誤時,它是不會被編譯的。忘記閉合<li>標籤了?難道你不想在你輸入錯誤的HTML時獲得豐富的反饋麼?

ReactifyError: /components/header.js: Parse Error: Line 23: Expected corresponding JSX closing tag for li while parsing file: /components/header.js

有了JSX,這樣豐富的錯誤反饋終於成爲現實!靠這一點JSX絕對完勝。如此快速而又豐富的反饋極大的提升了生產效率。正如我在個人Clean Code課程中討論的那樣————良好的工程解決方案遵循速錯原則。(譯者注:原文是:well- engineered solutions fail fast,關於fail fast能夠查看http://geeklu.com/2010/07/fai... 進行了解)

充分利用JavaScript(Leverage the Full Power of JavaScript)

使用JavaScript編寫你的標記,意味着這些標記能夠藉助JavaScript的所有能力,而不是像Angular或者Knockout這種以HTML爲中心的框架只能提供有限的特殊標記。(譯者注:我認爲這裏做者的表述並不許確,Angular也一樣能夠自由擴展HTML,只不過沒有React那麼靈巧方便)。

Client-side frameworks shouldn’t require you to learn a proprietary syntax for declaring loops and conditionals.
客戶端框架不該當要求使用者學習特殊的語法來聲明循環或者條件語句。

React減小了使用者學習另外一種特殊的聲明循環和基本條件語句的成本。你能夠看看第二階段中提到的幾個框架,他們實現雙向綁定的方式都是依靠一些屬於他們本身的特殊語法。相反,JSX看上去和HTML幾乎同樣,像循環和條件語句,徹底依賴原生的JavaScript。與衆多的JavaScript框架相比,不須要去學習相似於數據綁定等特殊語法,這一點又讓React和JSX脫穎而出。

而且,因爲你將這些標記與相關聯的JavaScript數據寫在一個文件中,當你引用函數時,許多IDE可以提供一些智能提示。想一想當你使用那些以HTML爲中心的框架時,調用一個function卻老是輸入錯誤時的苦惱吧!

Final Thoughts

JSX並不一個瘋狂的主意,它就是一段很正常的程序,所以不要再反感它了。

JSX isn’t revolutionary. It’s evolutionary.

JSX不是革命,它只是進化發展的結果。

像不少進化、演變同樣,它給咱們帶來的是一種改善。

原文連接:https://medium.com/@housecor/...

相關文章
相關標籤/搜索