優勢:
1.不需宣告,甚至匿名方式原地定義。編碼量少。
這一條在C++中尤其明顯,以繫結一個回撥為例,需要宣告,定義,呼叫繫結,三處程式碼。雖然C++11中支援lambda表示式,對於回撥的寫法有很大改進。但是其他地方依然蛋疼。
2.弱型別語言,一般情況下,不需關心實際型別。Debug時除外。
在使用C++這種強型別語言的開發中,尤其是寫功能程式碼時,型別檢查遠不如想象中那麼有用,很多時候反而是問題根源,編譯不通過時,很大一部分時間是在對變數型別,由此還衍生出一些特殊技術手段,比如介面卡模式等等。
使用JS這種弱型別語言,只要介面名稱能對上,那麼在物件的函式被呼叫時就認為是正確的。簡單說,只要長得像某一型別就行了,不需要必須是某一型別。
C++11中auto關鍵字也可以提升編碼速度(和JS的var很類似,可以隨時無腦輸出),不過看了一下引擎附帶的幾個例子程式碼,好像有濫用auto的趨勢。
3.指令碼語言動態擴充套件能力強,可以不必構造很多臨時型別和訊息型別。
比如,在大型遊戲中,全域性使用訊息機制時,C++可能用結構體,自定義類,或者我們以前直接丟JSON物件過去。在JS裡面就很簡單了,直接扔JSON物件吧。
在執行時可以動態給一個物件新增函式和屬性,而不需要重新構造新類和初始化。JSON源自JS,JSON是天然的訊息物件,非常合適。當然JSON有自身的缺點,訪問父節點和兄弟節點不太方便。並且JSON的結構和二維表沒法完全相容,這是一直讓策劃和工具程式設計師頭痛的一個問題。
4.語法靈活,可以支援各種編碼方式。隨機應變。
業界普遍認為物件導向在影像程式設計是最好的。但對於事件處理邏輯處理AI處理來說,物件導向則是羅嗦的要死。比如,我實在對觀察者模式提不起興趣,Qt中的訊號槽機制優雅的多。又比如我曾經做了一個A*演算法程式碼,想改成好用的物件導向方式,發現很痛苦。
JS很靈活,適合什麼樣的編碼方式,就用什麼樣的方式。
5.在語言級別天生整合了兩種最有用的資料結構,向量和對映表。
記得在KJava時代,MIDP的裡面只有很少的資料結構,裡面就有向量和哈西表。這兩種是最為常用的。JS在語言層面提供了支援,編碼極其方便。
6.指令碼語言無需編譯,大量節約了開發時間。
如果你在Mac上,並且開了虛擬機器然後編譯VS的話,應該有那個恐怖的按小時計算的編譯時間長度經驗。Clang雖然速度比VC快很多,但是每次如果clean一下然後編譯幾十上百個檔案也需要若干分鐘。
一些問題:
1.太靈活,更容易出爛程式碼。
2.除錯問題與IDE問題。
目前在cocos2d-x領域,還缺乏好用的支援JS的IDE。現在目前暫時還是用cocos2d-html5版本做除錯(兩者的介面已經高度一致化),未來會有基於c++的IDE做的JS除錯外掛(比如在Eclipse上面的)。
3.善變的this
this關鍵字絕對是JS裡面的變形金剛。根據不同的上下文,經常會變成其他東西。
這個經常會和回撥函式問題糾纏不清,如果再加上閉包,三合一,夠你喝一壺的。
4.閉包
閉包很強大,無限制傳參,抓取快照。
但是閉包本身的問題也不小,首先是閱讀和理解上的困難,物件導向的程式設計師一上來很難理解這東西,從他們的角度看閉包的程式碼也很醜。
還有就是效率問題,同事測了一下SpiderMonkey中的閉包在生成大物件時效率不太高。
目前在cocos2d-x前端開發中,為了防止出現問題,對於缺乏經驗的程式設計師,儘量不要使用閉包程式碼。
我個人在回合制戰報,生成動畫裡是用了一些閉包的,不過那是一次性程式碼。
5.變數生命週期不明確
變數生命週期問題,因為不需要宣告,很多時候也沒有特別明顯的初始化,並不能通過閱讀程式碼明確知道,一個變數的生存週期,這是所有指令碼語言和GC語言的特性,有些時候對除錯會形成麻煩。
6.原型繼承
難以理解的原型繼承。熟悉物件導向的人一般都對這個東西莫名其妙。
從靜態語言過度到動態指令碼語言,一般程式設計師會疑惑在幾個地方,this,閉包,原型繼承,以及如何靈活地使用指令碼語言的動態性進行編碼,我觀察了一下,很多人寫JS像靜態語言,還是c++風格或者Java風格。