鍍金池/ 教程/ C/ JS 腳本語(yǔ)言的優(yōu)勢(shì)與一些問(wèn)題
cocos2d-x for js 中的繼承
JS 與 C++ 的交互 1——JS 代碼調(diào)用 C++ 代碼
迎接腳本時(shí)代的到來(lái)
解決在 vs 中修改 js 源文件無(wú)效
JS 腳本語(yǔ)言的優(yōu)勢(shì)與一些問(wèn)題
注冊(cè)函數(shù)
回調(diào)函數(shù) 2
cxx-generator JS 綁定工具
使用 cocos2d-console 工具轉(zhuǎn)換腳本為字節(jié)碼
hybrid 開(kāi)發(fā)模式
JS 與 C++ 的交互 2——JS 與 C++ 的“函數(shù)重載”問(wèn)題
回調(diào)函數(shù)1——按鍵回調(diào)
Google 的繼承寫(xiě)法解析
John Resiq 的繼承寫(xiě)法解析
JS 與 C++ 的交互 3——C++ 和 JS 類(lèi)型轉(zhuǎn)換
傀儡構(gòu)造函數(shù)

JS 腳本語(yǔ)言的優(yōu)勢(shì)與一些問(wèn)題

優(yōu)勢(shì):

  1. 不需聲明,甚至匿名方式原地定義。編碼量少。 這一條在 C++ 中尤其明顯,以綁定一個(gè)回調(diào)為例,需要聲明,定義,調(diào)用綁定,三處代碼。雖然 C++11 中支持 lambda 表達(dá)式,對(duì)于回調(diào)的寫(xiě)法有很大改進(jìn)。但是其他地方依然蛋疼。

  2. 弱類(lèi)型語(yǔ)言,一般情況下,不需關(guān)心實(shí)際類(lèi)型。Debug 時(shí)除外。 在使用 C++ 這種強(qiáng)類(lèi)型語(yǔ)言的開(kāi)發(fā)中,尤其是寫(xiě)功能代碼時(shí),類(lèi)型檢查遠(yuǎn)不如想象中那么有用,很多時(shí)候反而是問(wèn)題根源,編譯不通過(guò)時(shí),很大一部分時(shí)間是在對(duì)變量類(lèi)型,由此還衍生出一些特殊技術(shù)手段,比如適配器模式等等。
    使用 JS 這種弱類(lèi)型語(yǔ)言,只要接口名稱(chēng)能對(duì)上,那么在對(duì)象的函數(shù)被調(diào)用時(shí)就認(rèn)為是正確的。簡(jiǎn)單說(shuō),只要長(zhǎng)得像某一類(lèi)型就行了,不需要必須是某一類(lèi)型。
    C++11 中 auto 關(guān)鍵字也可以提升編碼速度(和 JS 的 var 很類(lèi)似,可以隨時(shí)無(wú)腦輸出),不過(guò)看了一下引擎附帶的幾個(gè)例子代碼,好像有濫用 auto 的趨勢(shì)。

  3. 腳本語(yǔ)言動(dòng)態(tài)擴(kuò)展能力強(qiáng),可以不必構(gòu)造很多臨時(shí)類(lèi)型和消息類(lèi)型。 比如,在大型游戲中,全局使用消息機(jī)制時(shí),C++ 可能用結(jié)構(gòu)體,自定義類(lèi),或者我們以前直接丟J SON 對(duì)象過(guò)去。在 JS 里面就很簡(jiǎn)單了,直接扔 JSON 對(duì)象吧。 在運(yùn)行時(shí)可以動(dòng)態(tài)給一個(gè)對(duì)象添加函數(shù)和屬性,而不需要重新構(gòu)造新類(lèi)和初始化。JSON 源自 JS,JSON 是天然的消息對(duì)象,非常合適。當(dāng)然 JSON 有自身的缺點(diǎn),訪(fǎng)問(wèn)父節(jié)點(diǎn)和兄弟節(jié)點(diǎn)不太方便。并且 JSON 的結(jié)構(gòu)和二維表沒(méi)法完全兼容,這是一直讓策劃和工具程序員頭痛的一個(gè)問(wèn)題。

  4. 語(yǔ)法靈活,可以支持各種編碼方式。隨機(jī)應(yīng)變。 業(yè)界普遍認(rèn)為面向?qū)ο笤趫D像編程是最好的。但對(duì)于事件處理邏輯處理AI處理來(lái)說(shuō),面向?qū)ο髣t是羅嗦的要死。比如,我實(shí)在對(duì)觀察者模式提不起興趣,Qt 中的信號(hào)槽機(jī)制優(yōu)雅的多。又比如我曾經(jīng)做了一個(gè) A* 算法代碼,想改成好用的面向?qū)ο蠓绞?,發(fā)現(xiàn)很痛苦。
    JS 很靈活,適合什么樣的編碼方式,就用什么樣的方式。

  5. 在語(yǔ)言級(jí)別天生集成了兩種最有用的數(shù)據(jù)結(jié)構(gòu),向量和映射表。 記得在 KJava 時(shí)代,MIDP 的里面只有很少的數(shù)據(jù)結(jié)構(gòu),里面就有向量和哈西表。這兩種是最為常用的。JS 在語(yǔ)言層面提供了支持,編碼極其方便。

  6. 腳本語(yǔ)言無(wú)需編譯,大量節(jié)約了開(kāi)發(fā)時(shí)間。 如果你在 Mac 上,并且開(kāi)了虛擬機(jī)然后編譯 VS 的話(huà),應(yīng)該有那個(gè)恐怖的按小時(shí)計(jì)算的編譯時(shí)間長(zhǎng)度經(jīng)驗(yàn)。Clang 雖然速度比 VC 快很多,但是每次如果 clean 一下然后編譯幾十上百個(gè)文件也需要若干分鐘。

一些問(wèn)題:

  1. 太靈活,更容易出爛代碼。

  2. 調(diào)試問(wèn)題與 IDE 問(wèn)題。
    目前在 cocos2d-x 領(lǐng)域,還缺乏好用的支持 JS 的 IDE ?,F(xiàn)在目前暫時(shí)還是用 cocos2d-html5 版本做調(diào)試(兩者的接口已經(jīng)高度一致化),未來(lái)會(huì)有基于 c++ 的 IDE 做的 JS 調(diào)試插件(比如在 Eclipse 上面的)。

  3. 善變的 this
    this 關(guān)鍵字絕對(duì)是 JS 里面的變形金剛。根據(jù)不同的上下文,經(jīng)常會(huì)變成其他東西。 這個(gè)經(jīng)常會(huì)和回調(diào)函數(shù)問(wèn)題糾纏不清,如果再加上閉包,三合一,夠你喝一壺的。

  4. 閉包
    閉包很強(qiáng)大,無(wú)限制傳參,抓取快照。 但是閉包本身的問(wèn)題也不小,首先是閱讀和理解上的困難,面向?qū)ο蟮某绦騿T一上來(lái)很難理解這東西,從他們的角度看閉包的代碼也很丑。 還有就是效率問(wèn)題,同事測(cè)了一下 SpiderMonkey 中的閉包在生成大對(duì)象時(shí)效率不太高。 目前在 cocos2d-x 前端開(kāi)發(fā)中,為了防止出現(xiàn)問(wèn)題,對(duì)于缺乏經(jīng)驗(yàn)的程序員,盡量不要使用閉包代碼。 我個(gè)人在回合制戰(zhàn)報(bào),生成動(dòng)畫(huà)里是用了一些閉包的,不過(guò)那是一次性代碼。

  5. 變量生命周期不明確
    變量生命周期問(wèn)題,因?yàn)椴恍枰暶?,很多時(shí)候也沒(méi)有特別明顯的初始化,并不能通過(guò)閱讀代碼明確知道,一個(gè)變量的生存周期,這是所有腳本語(yǔ)言和 GC 語(yǔ)言的特性,有些時(shí)候?qū)φ{(diào)試會(huì)形成麻煩。

  6. 原型繼承
    難以理解的原型繼承。熟悉面向?qū)ο蟮娜艘话愣紝?duì)這個(gè)東西莫名其妙。

從靜態(tài)語(yǔ)言過(guò)度到動(dòng)態(tài)腳本語(yǔ)言,一般程序員會(huì)疑惑在幾個(gè)地方,this,閉包,原型繼承,以及如何靈活地使用腳本語(yǔ)言的動(dòng)態(tài)性進(jìn)行編碼,我觀察了一下,很多人寫(xiě) JS 像靜態(tài)語(yǔ)言,還是 c++ 風(fēng)格或者 Java 風(fēng)格。