如何看待 Angular 2.0 使用的 AtScript 是 TypeScript 的超集?

之前以為是媒體誤讀, 看了視頻確認確實如此. Hevery 也提到這樣一來 (Google 和 Microsoft 一起) 可以將相關內容促成標準. https://www.youtube.com/watch?v=lGdnh8QSPPk

如何看待 Google 此舉更全面的考慮, 以及對 Dart / ES 7 等的影響?


很嚴肅地感謝邀請。這問題我猶豫了很久才來答,因為覺得自己對語言所知不過皮毛,既然有好幾個人邀請我答,那就當拋磚引玉吧。

AtScript這門語言是由Google的Angular團隊創建的,最直接的目的是用於編寫Angular2.0,注意這裡為什麼說Angular,而不是說AngularJS,是因為Angular還存在一個Dart版本,也就是AngularDart。當前版本的Angular是需要維護JavaScript和Dart兩套代碼的,在2.0中,就只會有一套了。

有時候會覺得國外大公司真是小題大做,為了一個應用框架而創建一門新語言,聽上去很不可思議,但認真想想,這裡面有很多權衡。

既然談AtScript,就免不了要談Angular2.0,這是超越1.x版本的一次徹底革新。這麼激進的革新,出發點在哪裡呢?除了解決自身的一些問題,更重要的意義在於對未來標準的迎合,這些標準主要包括:

- module

- Web Components

- class

- observe

- promise

module的問題很好理解,JavaScript第一次有了語言上的模塊機制,而Web Components則是約定了基於泛HTML體系構建組件庫的方式,class增強了編程體驗,observe提供了數據和展現分離的一種優秀方式,promise則是目前前端最流行的非同步編程方式。

從以上幾個方面,我們可以很清楚地看到這些東西想要解決的問題,那就是:Web應用的大型化。何謂大型化?這個大,更多指的是高樓大廈之大,而不是一大片園林的大。

最近這些年我們也可以看出,整個Web生態是逐步嚮應用化傾斜的,越來越大比例的Javascript代碼被用於構建應用型網站,或者各類本地應用,Hybrid應用,而不是展示型網站。之前版本的JavaScript在構建大型Web應用的過程中,是存在一定不足的。

我曾經有個比喻,把Java、C#這類東西比喻成鋼筋混凝土,JavaScript比喻成竹木,兩者各有其適合的領域,其中也有重疊。亭台樓閣,輕靈精巧,如果不用竹木搭建,遍身都是土氣。如果蓋摩天大樓,也硬要用竹木搭建,恐怕不太合適。

我們現在所看到的絕大多數JavaScript應用的規模都嚴重偏小,傳統軟體廠商做出的Office,PhotoShop,AutoCAD,Matlab,還有魔獸、文明這類大型遊戲,如果想要用任何一種腳本語言去實現,都會面臨很多困難,那就是大規模協作的不便利性。

人類工業史上有不少優秀產品,易於生產,經久耐用,比如桑塔納轎車,比如AK47突擊步槍,這類產品的共同特點是皮實,不容易壞,即使壞了也容易修。在工業時代,組織任何領域的大型工程,都應當盡量把實現搞得簡單一些。

所以從這個角度可以解釋Java的流行,儘管黑它的人很多,但它在大型軟體的協作中,確實有獨特的優勢。只需經過較少的培訓,就可以上手使用,出現問題也容易定位,大型軟體的開發過程就需要這個。

如果使用JavaScript編寫大型應用,可能就會有些麻煩了,但是對此,經常會有人表示不服,理由往往是:誰說JavaScript不能寫大型應用,是他們水平不行,換我寫就可以。

確實如此。可是我們要的是:換大部分人寫都可以,而不是只限定少數幾個人才能寫。弱類型的語言給新手用,出問題的概率比強類型的語言多多了。所以,從工程化的角度看,如果存在一種容易編寫的強類型語言,又存在可靠的從這種語言到JavaScript的轉譯器,會是一件好事。

那麼,為什麼我們不直接用Java來編寫,然後編譯到JavaScript,而是非要重新搞一種語言呢?如果用Java,那不就是GWT乾的事情嗎?為什麼GWT已經成為淘汰的技術?這是否說明所有轉譯的語言都沒有前途,也沒有意義呢?

並非如此。提到AtScript,我們就不能不提另外幾種類似的語言,CoffeeScript,TypeScript,Dart。這幾種語言里只有TypeScript的願景是與AtScript基本一致的,CoffeeScript的應用層次是最淺的,主要是提供編寫的便利,轉換成JavaScript是它的宿命。Dart的目標並非為了編譯到別的語言,而是作為自己獨立的運行時存在。

而TypeScript和AtScript,都是以提高JavaScript項目的可控度為目標的,這兩個東西跟GWT之類東西相比,主要差異在於它們自身跟JavaScript的理念是一致的,包括原型繼承的方式,還有對ES6等相關標準的兼容性,所以其轉換更加自然,這兩種語言就是以JavaScript為目標構造的,當然比一個不相關的Java語言轉換來得靠譜。

TypeScript更多地像是一種對JavaScript未來標準的提前兼容,可以理解為強類型的JavaScript,使用它編寫代碼基本跟用ES6沒太大差別。

關於這三種語言的討論,參見這個話題:

Dart、CoffeeScript、TypeScript 和 JavaScript 哪種最適合專門學習? - 前端開發

我們在大型工程中,為了組件的隔離,常常會用到依賴注入之類的技術,但是在JavaScript中實現依賴注入,就會存在類型不可預知等狀況:

AngularJS中的依賴注入實際應用場景? - 徐飛的回答

如果有了類型約束,這個事情就好解決了。

AtScript在TypeScript的基礎上又加了一些東西,主要是註解。怎麼理解註解這個東西的作用呢,相當於給類型添加了更多的配置信息,而且運行時可讀取,這就是所謂的元數據。這塊東西其實也是代碼,只是通過另外一些方式存在。

註解的意義主要在於為類型添加特定的約束,好比一個類型是一張紙牌,有註解的類型相當於在紙牌背面貼了額外的標籤。如果是正常使用這個類,可以就當註解不存在,只看正面就行了,如果想要拿這個類來作特殊用途,就可以把牌反過來看看,看哪些標籤上給了什麼額外的信息。

比如說,在組件化體系中,某個類被當做組件類的時候,可能需要額外的配置信息,如果沒有註解的話,也可以在類上面放靜態變數來實現,但不優雅。語言支持註解的話,寫到註解上,就比較優雅了,類的實現中只寫具體功能的實現。

@Component({selector: "foo"})
export class MyComponent {
constructor(server:Server) {
this.server = server;
}
}

看這個例子裡面那個@Component的一段,如果以MyComponent類的本身功能來說,有沒有這句都不會影響這個類主體功能的實現,但我們可能在特定框架(Angular)中,需要把它與界面上某種DOM元素的選擇器關聯起來,就可以添加這麼一句註解,然後,僅僅在Angular的框架中去讀取並使用它即可,其他框架則無視之。

此外,註解對代碼文檔生成的作用應當比注釋更大,因為註解格式可以有編譯期檢查,而注釋沒有,根據註解,甚至還能在運行時生成文檔。

由於AtScript會編譯成JavaScript運行,它的註解也會轉換成某種用JavaScript直接實現的方式,類似我們之前在AngularJS 1.x版本中常見的那種,在構造函數上添加額外的屬性。

關於AtScript和Angular之間的淵源,可以參見我這篇翻譯中的部分:

[翻譯]有關Angular 2.0的一切 · Issue #8 · xufei/blog · GitHub

當時翻譯得比較倉促,也沒有再詳細修改,湊合看看吧,看不下去的請看原文。

說到這裡,該說說我對AtScript的整體評價了。我認為這也是一種賭博,賭的是Web應用加速發展,但瀏覽器中的各項標準未能如預期那樣快速推進。當Web應用逐步大型化,人們必然會追求更多工程上的可控手段,如果ES6和ES7能迅速推進,AtScript的生存狀況就堪憂,如果標準不能迅速推進,瀏覽器市場跟現在一樣亂,新的來了,老的未去,那這類轉換型語言還是有生存空間的。

從我個人的角度,是很樂於見到AtScript和TypeScript合併的,到現在這個階段還這麼分裂,不是一件好事,但是不是能這樣就不知道了。AtScript的發展絕對不會影響到ES6和ES7這條線,也不會影響Dart,因為AtScript的目標語言之一就是Dart,但Dart自身的發展已經不樂觀了,等AtScript成熟了,它更凄涼了。從成本角度,寫AtScript可以轉換成Dart,又可以轉換成ES,在形勢不明朗的時候,這個騎牆選擇顯然要比直接寫Dart好。

終於寫完,水平所限,只能這樣了,給初學者掃盲用吧,不對的歡迎各路大神評論指正。


AtScript 是可以做運行時類型檢查的("Instead we want to provide hooks for others to build runtime type assertion libraries ...",或者看題圖),TypeScript 運行時毛都沒有。Google 轉投 AtScript 就等於暫時放棄了這一點。

實際上,所謂 ES 7 decorator 和 AtScript annotation 的不同也正在此處。decorator 就是一個普通的函數,對你做些什麼,annotation 是一些元信息,你可以用某些東西(反射)去讀取它們(When we have annotations, it』s important to provide a consistent
API that developers and frameworks can leverage to gain access to this
information at runtime.)。雖然本質上可以互通,但是在重視程度、實現的優先順序上有別。TypeScript 是不超出 ES 的,它實現的是 decorator,這意味著它不會著急去實現反射。

所以說,Google 放棄 AtScript 轉投 TypeScript,實際上放棄了很重要的藍圖,這很坑。本來 AtScript 是介於 JavaScript 和 Dart 中間的,在 JS 虛擬機上增強了一些運行時,彷如 Objective-C 之於 C。而現在呢,TypeScript 只在編譯時生效,還沒有類型推導,著實顯得臃腫累贅。

當然,他們可能基於市場的考慮,覺得放棄反射,換取一部分市場和社區更有益。或者他們覺得運行時類型不是很必要(但是 JS 很多坑是無法通過編譯時檢查消除的)。

關於 Google 原來的願景,參考:AtScript Primer - Google Docs

關於反射,參考:Suggestion: reflection for interface? · Issue #1549 · Microsoft/TypeScript · GitHub


GWT不是淘汰的技術。Google很多產品 / 組都在用,2.8 / 3.0也在加緊開發中。


剛發布的新結果:https://twitter.com/ngconf/status/573521849780305920

AtScript is Typescript

這樣社區就不必分裂了


TypeScript團隊宣布與Angular團隊合作

自Angular 2.0開始,該JavaScript庫將使用TypeScript開發,而AtScript項目會終止。

原來Angular升級到2.0還發生了這麼多故事。。。


推薦閱讀:

如何看待Google和Microsoft在Angular JS 2 和 TypeScript上的合作?

TAG:前端開發 | 編程語言 | 編程 | TypeScript | AngularJS |