參考egret編譯順序說明
我們知道 JavaScript 是一種腳本語(yǔ)言焦辅,瀏覽器按腳本的順序來執(zhí)行泞当。實(shí)際上瀏覽器會(huì)根據(jù) <script> 標(biāo)簽?zāi)_本來載入順序來執(zhí)行腳本侍匙。當(dāng)我們的腳本引用了一個(gè)未載入的腳本中的變量時(shí),瀏覽將報(bào)出相應(yīng)的錯(cuò)誤绍刮。
一般情況下我們?cè)?Egret 項(xiàng)目中并不需要手動(dòng)處理編譯順序,因?yàn)槲覀兊木幾g器已經(jīng)幫助我們處理好了挨摸。但是有一種情況是編譯器不能處理的孩革,需要我們手動(dòng)加上 <reference> 標(biāo)簽來告訴編譯器我們的類的依賴關(guān)系。
首先我們建立幾個(gè)測(cè)試類得运,項(xiàng)目的結(jié)構(gòu)如下:
如上所示膝蜈,創(chuàng)建了一個(gè) Test 文件夾锅移,內(nèi)部創(chuàng)建了 Call 文件夾,在 Call 內(nèi)部創(chuàng)建了 TestCall.ts饱搏。同時(shí)在 Test 文件夾內(nèi)創(chuàng)建 TestA.ts 和 TestB.ts非剃。其余的 Main.ts 和 LoadingUI.ts 這里用不到,我們并不用去關(guān)注它們推沸。
在 TestA.ts 中代碼如下:
class TestA{
public static arr:Array<any> = ["t","e","s","t","c","a","l","l"];
}
TestB.ts 中代碼如下:
class TestB{
public static testBStr:string = TestA.arr.join("");
}
這兩個(gè)類內(nèi)容很簡(jiǎn)單备绽,都只有一個(gè)靜態(tài)成員。其中 TestA 類存放了一個(gè)數(shù)組,TestB 類將這個(gè)數(shù)組的內(nèi)容拼接成一個(gè)字符串并保存下來坤学。到目前為止我們編譯運(yùn)行并沒有發(fā)現(xiàn)異常疯坤。
下面在TestCall.ts 中加入對(duì) TestB 類的調(diào)用。
class TestCall{
public static test:any = egret.getDefinitionByName(TestB.testBStr);
}
編譯運(yùn)行之后發(fā)現(xiàn)瀏覽器會(huì)報(bào)如下TestB.js:11 Uncaught ReferenceError錯(cuò)誤:
那么當(dāng)我們添加了 TestB.testBstr的調(diào)用之后瀏覽器發(fā)現(xiàn) TestA 類并沒有被定義深浮,進(jìn)而導(dǎo)致 testBStr 這個(gè)屬性頁(yè)找不到了压怠。當(dāng)我們編譯之后發(fā)生了什么呢,檢查一下生成的 index.html 文件會(huì)發(fā)現(xiàn) TestB.js 是在 TestCall.js 之前加載的飞苇,而 TestA.js 是在最后加載的菌瘫。當(dāng) TestB.js 調(diào)用 TestA.js 中的文件的內(nèi)容時(shí)瀏覽器將會(huì)報(bào)錯(cuò)。
上面的調(diào)用關(guān)系在代碼中顯然是成立的布卡,編譯器并沒有報(bào)錯(cuò)雨让。而編譯器并沒有生成正確的載入順序,主要是因?yàn)槠錈o法確認(rèn)這種類的靜態(tài)成員的互相引用的順序忿等。當(dāng)在 TestCall.ts 中引用了TestB.ts 中的內(nèi)容時(shí)自動(dòng)將 TestB.js 放在 TestCall.js 之前進(jìn)行加載栖忠。由于無法檢測(cè)到 TestB.ts 中對(duì) TestA.ts 的靜態(tài)成員的引用,所以導(dǎo)致了以上情況的發(fā)生贸街。
解決方法
這種情況解決方法也很簡(jiǎn)單庵寞,就是告訴編譯器我們的類的依賴關(guān)系。在 TypeScript 中薛匪,使用<reference>標(biāo)簽來表示引用關(guān)系捐川。在 reference 標(biāo)簽中可以標(biāo)記依賴文件的相對(duì)路徑。所以只需要在 TestB 類之前加入如下注釋即可:
///<reference path="TestA.ts" />
class TestB{
public static testBStr:string = TestA.arr.join("");
}
上面這種情況一般發(fā)生在靜態(tài)成員的引用上逸尖,還有其他情況在極小概率下可能導(dǎo)致該現(xiàn)象古沥,如果遇到可以加入依賴關(guān)系標(biāo)簽來告訴編譯器正確的加載方式。
參考
js文件三斜杠注釋///reference path用途
編輯某個(gè)js文件時(shí)娇跟,要想這個(gè)js文件出現(xiàn)其他js成員的ide提示岩齿,可以再js文件開頭使用3個(gè)斜杠注釋和reference指令的path指向此js文件路徑,這樣在編寫這個(gè)js文件時(shí)苞俘,ide就會(huì)自動(dòng)出現(xiàn)path指向的js文件中的成員盹沈。
如導(dǎo)入jquery框架,在vs2013中編寫js文件時(shí)苗胀,jquery的標(biāo)志性字符$就會(huì)自動(dòng)出現(xiàn)在ide中襟诸,并且其方法也會(huì)一起ide提示瓦堵,大大加快代碼編寫速度。
注意:reference注釋需要放在js文件開頭(并不需要一定是第一行歌亲,前面可以有空白行)菇用,但是前面只能是空白行,不能有其他js代碼陷揪。注釋需要為3個(gè)斜杠///惋鸥,經(jīng)測(cè)試多一個(gè)少一個(gè)都不行,應(yīng)該延續(xù)了C#的注釋悍缠∝孕澹可以使用注釋///reference導(dǎo)入多個(gè)會(huì)引用到的js文件。
///<reference path="jquery1.4.2.js">
///<reference path="hightlight.js">
提醒:js文件三斜杠注釋///reference path導(dǎo)入的文件是給ide用的飞蚓,你的html頁(yè)面注意一定也要導(dǎo)入對(duì)應(yīng)的js文件滤港,要不會(huì)報(bào)錯(cuò)。
參考
使用Typescript來寫javascript
TypeScript 三斜線指令
/// <reference path="../../libs/underscore.browser.d.ts"/>
它是一種注釋趴拧,告訴typescript編譯器溅漾,當(dāng)前文件使用了哪些聲明文件,以幫助編輯器提示信息著榴,及編譯器檢查類型添履。這種注釋很重要,如果后面的路徑不對(duì)脑又,則編譯會(huì)失敗暮胧。
引用的文件以 .d.ts 結(jié)尾,它們是一種聲明文件问麸,就像是c語(yǔ)言中的header文件往衷,只包含了類或函數(shù)的簽名,而沒有實(shí)際內(nèi)容口叙,用于編輯器提示和編譯器驗(yàn)證炼绘。它們的內(nèi)容形如:
declare interface UnderscoreVoidListIterator {
(element : any, index : number, list : any[]) : void;
}
declare interface UnderscoreMemoListIterator {
(memo : any, element : any, index : number, list : any[]) : any;
}
declare interface UnderscoreListIterator {
(element : any, index : number, list : any[]) : any;
}
這種文件很重要嗅战,因?yàn)槲覀円胧褂玫谌降膉s庫(kù)妄田,一般都需要手動(dòng)做出這樣的聲明文件,才能在typesafe的環(huán)境中使用它們驮捍。只需要以注釋的方式寫上即可疟呐,不需要在實(shí)際代碼中聲明或引用什么。