對于現代開發來說,Javascript就是一種垃圾語言

作者: julik live  發布時間: 2013-11-25 22:06  閱讀: 22139 次  推薦: 24   原文鏈接   [收藏]  

  英文原文:For modern development Javascript indeed is a s̶h̶i̶t̶ dissapointing language

  我很抱歉,但 Crockford 就是堅持這么寫的(I’m sorry, but the Crockford arguments do not cut it.)。

  Javascript 在很多方面都爛透了,而且還極其無趣。我就納了悶了,大家為啥都義無返顧、群情激奮的跳進 Node 學習的大軍里。是!Node 是比 Ruby 快,Node 是基于事件模型處理的,但讓我無法理解的是——一些人動不動就想把自己的程序用 Node 重構一下,過過腦子行嗎!

  Javascript 的繼承,深拷貝問題,不是定義一個新的 ECMA 標準就能解決的,不是套個漂亮的語法外殼(比如 CoffeeScript)就能搞定的,不是用 require 實現個標準化或者引入 classes 就可以萬事大吉的,ECMA 語言里不是有個引入 classes 的 ActionScript 嗎!那玩意跟 Javascript 一樣屎,只要大家繼續用它,PHP 框架的現狀就是 JS 的未來——一堆一堆的人前赴后繼,日以繼夜的為這坨屎一樣的語言搭框架、寫工具。

  我來說一下為什么 Javascript 糟糕,當然了,它也有好的方面。 但是問題就是太不實用,比如說原型繼承(prototypal inheritance)就限制頗多——因為這玩意說白了就是 function override,還有就是那句:“萬物皆 function” 也是相當的廢柴——因為 function 不是一個對象,也不能當做數據結構來承載數據。

  其實真正的吐槽才剛剛開始,隨便列幾個吧:

  JS 的調用屬性

  看這個屎一樣的設計,回顧過去,咱們很難苛責語言的設計人員,因為它們可能處于性能考慮。再者,如果不習慣消息-傳遞機制的語言的話,你會覺得“怎么一些屬性可以被調用而另外一些就不可以呢”!

  哈希對象對于 stable 鍵不可用

  對象和哈希的混合不是一個好點子,因為它違反了對象可以擁有 metadata 的前提,metadata 允許我們建立基本類型系統或者至少各種類型的 introspection。

  函數對象對于類型系統不可用,因為一個對象不攜帶任何類型信息

  這可是大事,Ruby 的世界里也是這樣,感覺所有的東西都在像鴨子一樣快樂的嘎嘎叫。我們經常用 Object$class 來獲取對象信息,下面是給 HTML 元素加樣式的標準的流程:

<div class='<%= model.class %>' id='<%= [model.class, model.id].join %>' >…

  在 JS 里是不可能的,因為只有'Object','function'和原始類型才有類型信息。

  到處是 Null

  不小心用錯了一個常量。

MyApp.SYNC <i>
// should have been MyApp.SYNC_FETCH</i>

  任何事情都不會發生,因為對象是 hashes,而且 js 給常量默認為0。 帶著錯誤 key 的常量將會是 undefined,而且還會滲透到被調用函數中,等出了事,慢慢跟蹤 debug 去吧。

  回調的深淵

  JS 缺少合適的 deferred 功能,不是多線程,就得靠事件化執行。你的調用會散落在各個事件回調中,代碼都完事了,回調還在那執行呢,比如,JS 干下面這個是就費勁。

var res = await AjaxReq.fetch ('/long-request')
// because you are waiting for a result, here the runtime would 
// schedule event handling, DOM redraws and whatever else it can 
// squeeze in while you await 
res.name 
// this will be only executed once res is available

  因為你在等一個結果,就在等待的這會,runtime 完全可以進行事件處理、DOM 重繪、干啥都行。

  res.name —— 等 res 可以使用的時候在去執行 res.name 的操作。

  當然了,JS 社區做了跟 PHP 社區一直以來一樣的事情——給 Javascript 這坨屎擦屁股,怎么擦呢?用更多的回調,好點的,就是回調鏈

when (<ERMAGHERD RIDICULOUSLY LONG CALLBACK>
 // 48 lines of code down 
) .then (<HOLYSHIT WHEN WILL THIS BE OVER> 

// 23 lines down 
) .then (<GIVE ME SOME COFFEE ALREADY>)

  一般情況下,加入一個 wait primitive 就在獲取結果的等待過程中控制 events。

  專業一點的做法就是啥玩意咱都異步,現實是你寫的代碼 80% 都是同步的,因為程序里 80% 干的都是——個操蛋的事情跟另外一個操蛋的事情一起搞,而且你需要它倆都它媽的完事了才行。

  可怕的異常處理機制

  異常處理在 JS 中機器可怕,一般形式——你可以查看調用堆棧(一堆匿名函數和好點的名字的函數),你可看到錯誤信息,我就提兩個經常碰到的錯誤:

undefined is not a function
cannot call property 'xyz' of undefined

  這都拜 Javascript 中“函數(泥煤)對象”所賜,根本沒有方法定義——它們只有屬性,JS 運行時永遠沒有辦法知道函數對象有沒有方法可以被調用,或者某個屬性名稱——它就認為你的哈希鍵不存在。

  我記得 Ruby 社區里的人抱怨 Ruby 的回溯和錯誤消息機制不好用,Rubinius 就給解決了。在泥煤的 Javascript 里,你知道錯誤消息特別亂嗎?因為有你想得到和使用的兩個最最基本、最最重要的異常 NameError 和 NoMethodError 都有可能,這在其它語言里都是不能理解的,但 Javascript 語言就這么馬馬虎虎的用起來了。

  不可否認,functions 是亮點,原型也是好東西,但是如果你想建立一個稍微復雜的 JS 應用,你就得這么寫:

var cv = Marionette.CollectionView.extend ({
  itemView: MyApp.Views.WidgetView;
});

  如果“MyApp.Views.WidgetView 還沒有定義”,你會得到啥錯誤?“undefined is not a function”。當然!你什么時候會得到呢?當 CollectionView 想要實例化你的視圖的時候,而不是當你定義變量 cv 的時候,你會忐忑好幾分鐘,直到你明白了這錯誤是哪里導致的。

  這是為啥呢?因為所有都是 hash, 而且這個語言不能做任何形式的 introspection。

  還有一個困擾我的事就是,有些大哥居然從 Ruby 轉戰 Node,還贊 Node 是個好東西。Node 也許是好寶貝,但是想想它內部運行著屎一樣的 Javascript 語言,我就由衷地想退避三舍。

  這么說吧,JS 一日不好用,我便一日不會用 Node,謝謝。

  我理解有一些人想跳出 MRI 架構,投身 Node,很簡單啊——你不會說日語, 所以你舔個臉說日語很難學,話撂這,你在 MRI 上的有精進的機會也它媽趨近于 0。

  JS 是屎,但凡我們有那么一絲絲的擔當,就該盡自己的綿薄之力要么讓它壽終正寢,要么幫助它更上一層樓,天天在那沾沾自喜對它的發展沒有一點幫助,CoffeeScript 做的還遠遠不夠。

  更新:看這里,我不是一個人在戰斗

譯者注:julik live 博主后來把標題改為了“For modern development Javascript indeed is a s̶h̶i̶t̶ dissapointing language”。另外,他博客頁腳不美觀,占用空間過大,在原文評論中被很多讀者吐槽了。當然了,也有熱心網友在幫他出主意了。

  翻譯: 伯樂在線 - 黃利民 譯文鏈接: http://blog.jobbole.com/50671/

24
54
 
標簽:Javascript
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()