(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范_第1頁(yè)
(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范_第2頁(yè)
(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范_第3頁(yè)
(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范_第4頁(yè)
(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范_第5頁(yè)
已閱讀5頁(yè),還剩37頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范/(設(shè)計(jì)參考規(guī)范)JAVASCRIPT開(kāi)發(fā)規(guī)范JAVASCRIPT開(kāi)發(fā)規(guī)范一、JavaScript語(yǔ)言規(guī)范JavaScript是一種客戶(hù)端腳本語(yǔ)言,Google的許多開(kāi)源工程中都有用到它.這份指南列出了編寫(xiě)JavaScript時(shí)需要遵守的規(guī)則.Alipay前端JavaScript以些規(guī)范為準(zhǔn),局部有所修改

注:http:///svn/trunk/javascriptguide.xml1.變量

聲明變量必須加上var關(guān)鍵字.Decision:當(dāng)你沒(méi)有寫(xiě)var,變量就會(huì)暴露在全局上下文中,這樣很可能會(huì)和現(xiàn)有變量沖突.另外,如果沒(méi)有加上,很難明確該變量的作用域是什么,變量也很可能像在局部作用域中,很輕易地泄漏到Document或者Window中,所以務(wù)必用var去聲明變量.2.常量常量的形式如:NAMES_LIKE_THIS,即使用大寫(xiě)字符,并用下劃線分隔.你也可用@const標(biāo)記來(lái)指明它是一個(gè)常量.但請(qǐng)永遠(yuǎn)不要使用const關(guān)鍵詞.Decision:

(1)對(duì)于基本類(lèi)型的常量,只需轉(zhuǎn)換命名.

/**

*Thenumberofsecondsinaminute.

*@type{number}

*/

goog.example.SECONDS_IN_A_MINUTE=60;

(2)對(duì)于非基本類(lèi)型,使用@const標(biāo)記.

/**

*Thenumberofsecondsineachofthegivenunits.

*@type{Object.<number>}

*@const

*/

goog.example.SECONDS_TABLE={

minute:60,

hour:60*60,

day:60*60*24

}

這標(biāo)記告訴編譯器它是常量.

至于關(guān)鍵詞const,因?yàn)镮E不能識(shí)別,所以不要使用.3.分號(hào)總是使用分號(hào).如果僅依靠語(yǔ)句間的隱式分隔,有時(shí)會(huì)很麻煩.你自己更能清楚哪里是語(yǔ)句的起止.而且有些情況下,漏掉分號(hào)會(huì)很危險(xiǎn):

//1.

MyCtotype.myMethod=function(){

return42;

}//Nosemicolonhere.

(function(){

//Someinitializationcodewrappedinafunctiontocreateascopeforlocals.

})();

varx={

'i':1,

'j':2

}//Nosemicolonhere.

//2.TryingtodoonethingonInternetExplorerandanotheronFirefox.

//Iknowyou'dneverwritecodelikethis,butthrowmeabone.

[normalVersion,ffVersion][isIE]();

varTHINGS_TO_EAT=[apples,oysters,sprayOnCheese]//Nosemicolonhere.

//3.conditionalexecutionalabash

-1==resultOfOperation()||die();

這段代碼會(huì)發(fā)生些什么詭異事呢?報(bào)JavaScript錯(cuò)誤-例子1上的語(yǔ)句會(huì)解釋成,一個(gè)函數(shù)帶一匿名函數(shù)作為參數(shù)而被調(diào)用,返回42后,又一次被"調(diào)用",這就導(dǎo)致了錯(cuò)誤.例子2中,你很可能會(huì)在運(yùn)行時(shí)遇到'nosuchpropertyinundefined'錯(cuò)誤,原因是代碼試圖這樣x[ffVersion][isIE]()執(zhí)行.當(dāng)resultOfOperation()返回非NaN時(shí),就會(huì)調(diào)用die,其結(jié)果也會(huì)賦給THINGS_TO_EAT.為什么?JavaScript的語(yǔ)句以分號(hào)作為結(jié)束符,除非可以非常準(zhǔn)確推斷某結(jié)束位置才會(huì)省略分號(hào).上面的幾個(gè)例子產(chǎn)出錯(cuò)誤,均是在語(yǔ)句中聲明了函數(shù)/對(duì)象/數(shù)組直接量,但閉括號(hào)('}'或']')并不足以表示該語(yǔ)句的結(jié)束.在JavaScript中,只有當(dāng)語(yǔ)句后的下一個(gè)符號(hào)是后綴或括號(hào)運(yùn)算符時(shí),才會(huì)認(rèn)為該語(yǔ)句的結(jié)束.遺漏分號(hào)有時(shí)會(huì)出現(xiàn)很奇怪的結(jié)果,所以確保語(yǔ)句以分號(hào)結(jié)束.4.嵌套函數(shù)可以使用嵌套函數(shù)很有用,比如,減少重復(fù)代碼,隱藏幫助函數(shù),等.沒(méi)什么其他需要注意的地方,隨意使用.5.塊內(nèi)函數(shù)聲明不要在塊內(nèi)聲明一個(gè)函數(shù),不要寫(xiě)成:

if(x){

functionfoo(){}

}雖然很多JS引擎都支持塊內(nèi)聲明函數(shù),但它不屬于ECMAScript規(guī)范(見(jiàn)ECMA-262,第13和14條).各個(gè)瀏覽器糟糕的實(shí)現(xiàn)相互不兼容,有些也與未來(lái)ECMAScript草案相違背.ECMAScript只允許在腳本的根語(yǔ)句或函數(shù)中聲明函數(shù).如果確實(shí)需要在塊中定義函數(shù),建議使用函數(shù)表達(dá)式來(lái)初始化變量:

if(x){

varfoo=function(){}

}6.異??梢阅阍趯?xiě)一個(gè)比較復(fù)雜的應(yīng)用時(shí),不可能完全避免不會(huì)發(fā)生任何異常.大膽去用吧.7.自定義異??梢杂袝r(shí)發(fā)生異常了,但返回的錯(cuò)誤信息比較奇怪,也不易讀.雖然可以將含錯(cuò)誤信息的引用對(duì)象或者可能產(chǎn)生錯(cuò)誤的完整對(duì)象傳遞過(guò)來(lái),但這樣做都不是很好,最好還是自定義異常類(lèi),其實(shí)這些基本上都是最原始的異常處理技巧.所以在適當(dāng)?shù)臅r(shí)候使用自定義異常.8.標(biāo)準(zhǔn)特性總是優(yōu)于非標(biāo)準(zhǔn)特性.最大化可移植性和兼容性,盡量使用標(biāo)準(zhǔn)方法而不是用非標(biāo)準(zhǔn)方法,(比如,優(yōu)先用string.charAt(3)而不用string[3],通過(guò)DOM原生函數(shù)訪問(wèn)元素,而不是使用應(yīng)用封裝好的快速接口.9.封裝基本類(lèi)型不要沒(méi)有任何理由去封裝基本類(lèi)型,另外還存在一些風(fēng)險(xiǎn):varx=newBoolean(false);

if(x){

alert('hi');//Shows'hi'.

}除非明確用于類(lèi)型轉(zhuǎn)換,其他情況請(qǐng)千萬(wàn)不要這樣做!varx=Boolean(0);

if(x){

alert('hi');//Thiswillneverbealerted.

}

typeofBoolean(0)=='boolean';

typeofnewBoolean(0)=='object';有時(shí)用作number,string或boolean時(shí),類(lèi)型的轉(zhuǎn)換會(huì)非常實(shí)用.10.多級(jí)原型結(jié)構(gòu)不是首選多級(jí)原型結(jié)構(gòu)是指JavaScript中的繼承關(guān)系.當(dāng)你自定義一個(gè)D類(lèi),且把B類(lèi)作為其原型,那么這就獲得了一個(gè)多級(jí)原型結(jié)構(gòu).這些原型結(jié)構(gòu)會(huì)變得越來(lái)越復(fù)雜!使用Arale中的inherits或其他類(lèi)似的用于繼承的函數(shù),會(huì)是更好的選擇.functionMyClass(){

doSomeThing()

}

arale.inherits(MyClass,Parent);

MyCtotype.method=function(){

...

};11.方法定義Ftotype.bar=function(){...};有很多方法可以給構(gòu)造器添加方法或成員,我們更傾向于使用如下的形式:Ftotype.bar=function(){

/*...*/

};12.閉包可以,但小心使用.閉包也許是JS中最有用的特性了.有一份比較好的介紹閉包原理的文檔.有一點(diǎn)需要牢記,閉包保留了一個(gè)指向它封閉作用域的指針,所以,在給DOM元素附加閉包時(shí),很可能會(huì)產(chǎn)生循環(huán)引用,進(jìn)一步導(dǎo)致內(nèi)存泄漏.比如下面的代碼:functionfoo(element,a,b){

element.onclick=function(){/*usesaandb*/};

}這里,即使沒(méi)有使用element,閉包也保留了element,a和b的引用,.由于element也保留了對(duì)閉包的引用,這就產(chǎn)生了循環(huán)引用,這就不能被GC回收.這種情況下,可將代碼重構(gòu)為:

functionfoo(element,a,b){

element.onclick=bar(a,b);

}

functionbar(a,b){

returnfunction(){/*usesaandb*/}

}13.eval()只用于解析序列化串(如:解析RPC響應(yīng))eval()會(huì)讓程序執(zhí)行的比較混亂,當(dāng)eval()里面包含用戶(hù)輸入的話就更加危險(xiǎn).可以用其他更佳的,更清晰,更安全的方式寫(xiě)你的代碼,所以一般情況下請(qǐng)不要使用eval().當(dāng)碰到一些需要解析序列化串的情況下(如,計(jì)算RPC響應(yīng)),使用eval很容易實(shí)現(xiàn).解析序列化串是指將字節(jié)流轉(zhuǎn)換成內(nèi)存中的數(shù)據(jù)結(jié)構(gòu).比如,你可能會(huì)將一個(gè)對(duì)象輸出成文件形式:users=[

{

name:'Eric',

id:37824,

email:'jellyvore@'

},

{

name:'xtof',

id:31337,

email:'b4d455h4x0r@'

},

...

];很簡(jiǎn)單地調(diào)用eval后,把表示成文件的數(shù)據(jù)讀取回內(nèi)存中.類(lèi)似的,eval()對(duì)RPC響應(yīng)值進(jìn)行解碼.例如,你在使用XMLHttpRequest發(fā)出一個(gè)RPC請(qǐng)求后,通過(guò)eval()將服務(wù)端的響應(yīng)文本轉(zhuǎn)成JavaScript對(duì)象:

varuserOnline=false;

varuser='nusrat';

varxmlhttp=newXMLHttpRequest();

xmlhttp.open('GET','http:///isUserOnline?user='+user,false);

xmlhttp.send('');

//Serverreturns:

//userOnline=true;

if(xmlhttp.status==200){

eval(xmlhttp.responseText);

}

//userOnlineisnowtrue.14.with(){}不要使用使用with讓你的代碼在語(yǔ)義上變得不清晰.因?yàn)閣ith的對(duì)象,可能會(huì)與局部變量產(chǎn)生沖突,從而改變你程序原本的用義.下面的代碼是干嘛的?with(foo){

varx=3;

returnx;

}答案:任何事.局部變量x可能被foo的屬性覆蓋,當(dāng)它定義一個(gè)setter時(shí),在賦值3后會(huì)執(zhí)行很多其他代碼.所以不要使用with語(yǔ)句.15.this僅在對(duì)象構(gòu)造器,方法,閉包中使用.this的語(yǔ)義很特別.有時(shí)它引用一個(gè)全局對(duì)象(大多數(shù)情況下),調(diào)用者的作用域(使用eval時(shí)),DOM樹(shù)中的節(jié)點(diǎn)(添加事件處理函數(shù)時(shí)),新創(chuàng)建的對(duì)象(使用一個(gè)構(gòu)造器),或者其他對(duì)象(如果函數(shù)被call()或apply()).使用時(shí)很容易出錯(cuò),所以只有在下面兩個(gè)情況時(shí)才能使用:

在構(gòu)造器中對(duì)象的方法(包括創(chuàng)建的閉包)中16.for-in循環(huán)只用于object/map/hash的遍歷對(duì)Array用for-in循環(huán)有時(shí)會(huì)出錯(cuò).因?yàn)樗⒉皇菑?到length-1進(jìn)行遍歷,而是所有出現(xiàn)在對(duì)象及其原型鏈的鍵值.下面就是一些失敗的使用案例:functionprintArray(arr){

for(varkeyinarr){

print(arr[key]);

}

}

printArray([0,1,2,3]);//Thisworks.

vara=newArray(10);

printArray(a);//Thisiswrong.

a=document.getElementsByTagName('*');

printArray(a);//Thisiswrong.

a=[0,1,2,3];

a.buhu='wine';

printArray(a);//Thisiswrongagain.

a=newArray;

a[3]=3;

printArray(a);//Thisiswrongagain.而遍歷數(shù)組通常用最普通的for循環(huán).

functionprintArray(arr){

varl=arr.length;

for(vari=0;i<l;i++){

print(arr[i]);

}

}17.關(guān)聯(lián)數(shù)組永遠(yuǎn)不要使用Array作為map/hash/associative數(shù)組.數(shù)組中不允許使用非整型作為索引值,所以也就不允許用關(guān)聯(lián)數(shù)組.而取代它使用Object來(lái)表示map/hash對(duì)象.Array僅僅是擴(kuò)展自O(shè)bject(類(lèi)似于其他JS中的對(duì)象,就像Date,RegExp和String)一樣來(lái)使用.18.多行字符串不要使用不要這樣寫(xiě)長(zhǎng)字符串:varmyString='AratherlongstringofEnglishtext,anerrormessage\

actuallythatjustkeepsgoingandgoing--anerror\

messagetomaketheEnergizerbunnyblush(rightthrough\

thoseSchwarzeneggershades)!WherewasI?Ohyes,\

you\'vegotanerrorandalltheextraneouswhitespaceis\

justgravy.Haveaniceday.';

在編譯時(shí),不能忽略行起始位置的空白字符;"\"后的空白字符會(huì)產(chǎn)生奇怪的錯(cuò)誤;雖然大多數(shù)腳本引擎支持這種寫(xiě)法,但它不是ECMAScript的標(biāo)準(zhǔn)規(guī)范.19.Array和Object字面量使用使用Array和Object語(yǔ)法,而不使用Array和Object構(gòu)造器.使用Array構(gòu)造器很容易因?yàn)閭鲄⒉磺‘?dāng)導(dǎo)致錯(cuò)誤.

//Lengthis3.

vara1=newArray(x1,x2,x3);

//Lengthis2.

vara2=newArray(x1,x2);

//Ifx1isanumberanditisanaturalnumberthelengthwillbex1.

//Ifx1isanumberbutnotanaturalnumberthiswillthrowanexception.

//Otherwisethearraywillhaveoneelementwithx1asitsvalue.

vara3=newArray(x1);

//Lengthis0.

vara4=newArray();如果傳入一個(gè)參數(shù)而不是2個(gè)參數(shù),數(shù)組的長(zhǎng)度很有可能就不是你期望的數(shù)值了.為了避免這些歧義,我們應(yīng)該使用更易讀的直接量來(lái)聲明.

vara=[x1,x2,x3];

vara2=[x1,x2];

vara3=[x1];

vara4=[];雖然Object構(gòu)造器沒(méi)有上述類(lèi)似的問(wèn)題,但鑒于可讀性和一致性考慮,最好還是在字面上更清晰地指明.

varo=newObject();

varo2=newObject();

o2.a=0;

o2.b=1;

o2.c=2;

o2['strangekey']=3;

應(yīng)該寫(xiě)成:

varo={};

varo2={

a:0,

b:1,

c:2,

'strangekey':3

};20.修改內(nèi)置對(duì)象的原型不要千萬(wàn)不要修改內(nèi)置對(duì)象,如Ototype和Atotype的原型.而修改內(nèi)置對(duì)象,如Ftotype的原型,雖然少危險(xiǎn)些,但仍會(huì)導(dǎo)致調(diào)試時(shí)的詭異現(xiàn)象.所以也要避免修改其原型.21.IE下的條件注釋不要使用不要這樣子寫(xiě):

varf=function(){

/@cc_onif(@_jscript){return2*@/3;/@}@/

};

條件注釋妨礙自動(dòng)化工具的執(zhí)行,因?yàn)樵谶\(yùn)行時(shí),它們會(huì)改變JavaScript語(yǔ)法樹(shù).二、JavaScript編碼風(fēng)格1.命名

通常,使用functionNamesLikeThis,variableNamesLikeThis,ClassNamesLikeThis,EnumNamesLikeThis,methodNamesLikeThis,和SYMBOLIC_CONSTANTS_LIKE_THIS.A.屬性和方法文件或類(lèi)中的私有屬性,變量和方法名應(yīng)該以下劃線"_"開(kāi)頭.保護(hù)屬性,變量和方法名不需要下劃線開(kāi)頭,和公共變量名一樣.

更多有關(guān)私有和保護(hù)的信息見(jiàn),visibility.B.方法和函數(shù)參數(shù)

可選參數(shù)以opt_開(kāi)頭.函數(shù)的參數(shù)個(gè)數(shù)不固定時(shí),應(yīng)該添加最后一個(gè)參數(shù)var_args為參數(shù)的個(gè)數(shù).你也可以不設(shè)置var_args而取代使用arguments.可選和可變參數(shù)應(yīng)該在@param標(biāo)記中說(shuō)明清楚.雖然這兩個(gè)規(guī)定對(duì)編譯器沒(méi)有任何影響,但還是請(qǐng)盡量遵守C.Getters和Setters

Getters和setters并不是必要的.但只要使用它們了,就請(qǐng)將getters命名成getFoo()形式,將setters命名成setFoo(value)形式.(對(duì)于布爾類(lèi)型的getters,使用isFoo()也可.)D.命名空間JavaScript不支持包和命名空間.不容易發(fā)現(xiàn)和調(diào)試全局命名的沖突,多個(gè)系統(tǒng)集成時(shí)還可能因?yàn)槊麤_突導(dǎo)致很?chē)?yán)重的問(wèn)題.為了提高JavaScript代碼復(fù)用率,我們遵循下面的約定以避免沖突.為全局代碼使用命名空間在全局作用域上,使用一個(gè)唯一的,與工程/庫(kù)相關(guān)的名字作為前綴標(biāo)識(shí).比如,你的工程是"ProjectSloth",那么命名空間前綴可取為sloth.*.

varsloth={};

sloth.sleep=function(){

...

};許多JavaScript庫(kù),包括theClosureLibraryandDojotoolkit為你提供了聲明你自己的命名空間的函數(shù).比如:

vide('sloth');

sloth.sleep=function(){

...

};明確命名空間所有權(quán)

當(dāng)選擇了一個(gè)子命名空間,請(qǐng)確保父命名空間的負(fù)責(zé)人知道你在用哪個(gè)子命名空間,比如說(shuō),你為工程'sloths'創(chuàng)建一個(gè)'hats'子命名空間,那確保Sloth團(tuán)隊(duì)人員知道你在使用sloth.hats.外部代碼和內(nèi)部代碼使用不同的命名空間"外部代碼"是指來(lái)自于你代碼體系的外部,可以獨(dú)立編譯.內(nèi)外部命名應(yīng)該嚴(yán)格保持獨(dú)立.如果你使用了外部庫(kù),他的所有對(duì)象都在foo.hats.*下,那么你自己的代碼不能在foo.hats.*下命名,因?yàn)楹苡锌赡芷渌麍F(tuán)隊(duì)也在其中命名.

foo.require('foo.hats');

/**

*WRONG--DoNOTdothis.

*@constructor

*@extend{foo.hats.RoundHat}

*/

foo.hats.BowlerHat=function(){

};

如果你需要在外部命名空間中定義新的API,那么你應(yīng)該直接導(dǎo)出一份外部庫(kù),然后在這份代碼中修改.在你的內(nèi)部代碼中,應(yīng)該通過(guò)他們的內(nèi)部名字來(lái)調(diào)用內(nèi)部API,這樣保持一致性可讓編譯器更好的優(yōu)化你的代碼.

vide('googleyhats.BowlerHat');

foo.require('foo.hats');

/**

*@constructor

*@extend{foo.hats.RoundHat}

*/

googleyhats.BowlerHat=function(){

...

};goog.exportSymbol('foo.hats.BowlerHat',googleyhats.BowlerHat);

重命名那些名字很長(zhǎng)的變量,提高可讀性主要是為了提高可讀性.局部空間中的變量別名只需要取原名字的最后部分.

/**

*@constructor

*/

space.MyClass=function(){

};

/**

*@param{space.MyClass}a

*/

space.MyClass.staticHelper=function(a){

...

};

myapp.main=function(){

varMyClass=space.MyClass;

varstaticHelper=space.MyClass.staticHelper;

staticHelper(newMyClass());

};

不要對(duì)命名空間創(chuàng)建別名.

myapp.main=function(){

varnamespace=space;

namespace.MyClass.staticHelper(newnamespace.MyClass());

};

除非是枚舉類(lèi)型,不然不要訪問(wèn)別名變量的屬性.

/**@enum{string}*/

space.Fruit={

APPLE:'a',

BANANA:'b'

};

myapp.main=function(){

varFruit=space.Fruit;

switch(fruit){

caseFruit.APPLE:

...

caseFruit.BANANA:

...

}

};myapp.main=function(){

varMyClass=space.MyClass;

MyClass.staticHelper(null);

};

不要在全局范圍內(nèi)創(chuàng)建別名,而僅在函數(shù)塊作用域中使用.E.文件名

文件名應(yīng)該使用小寫(xiě)字符,以避免在有些系統(tǒng)平臺(tái)上不識(shí)別大小寫(xiě)的命名方式.文件名以.js結(jié)尾,不要包含除-和_外的標(biāo)點(diǎn)符號(hào)(使用-優(yōu)于_).F.JS鉤子

JS鉤子一律使用"J-”前綴,如:#J-ui-repeater2.自定義toString()方法應(yīng)該總是成功調(diào)用且不要拋異常.可自定義toString()方法,但確保你的實(shí)現(xiàn)方法滿(mǎn)足:總是成功沒(méi)有其他負(fù)面影響.如果不滿(mǎn)足這兩個(gè)條件,那么可能會(huì)導(dǎo)致嚴(yán)重的問(wèn)題,比如,如果toString()調(diào)用了包含assert的函數(shù),assert輸出導(dǎo)致失敗的對(duì)象,這在toString()也會(huì)被調(diào)用.3.延遲初始化可以沒(méi)必要在每次聲明變量時(shí)就將其初始化.4.明確作用域任何時(shí)候都需要任何時(shí)候都要明確作用域-提高可移植性和清晰度.例如,不要依賴(lài)于作用域鏈中的window對(duì)象.可能在其他應(yīng)用中,你函數(shù)中的window不是指之前的那個(gè)窗口對(duì)象.5.代碼格式化

主要依照C++格式規(guī)范(中文版),針對(duì)JavaScript,還有下面一些附加說(shuō)明.A.大括號(hào)

分號(hào)會(huì)被隱式插入到代碼中,所以你務(wù)必在同一行上插入大括號(hào).例如:

if(something){

//...

}else{

//...

}B.數(shù)組和對(duì)象的初始化如果初始值不是很長(zhǎng),就保持寫(xiě)在單行上:

vararr=[1,2,3];//Nospaceafter[orbefore].

varobj={a:1,b:2,c:3};//Nospaceafter{orbefore}.初始值占用多行時(shí),縮進(jìn)2個(gè)空格.

//Objectinitializer.

varinset={

top:10,

right:20,

bottom:15,

left:12};

//Arrayinitializer.

this.rows_=[

'"Slartibartfast"<fjordmaster@>',

'"ZaphodBeeblebrox"<theprez@>',

'"FordPrefect"<ford@>',

'"ArthurDent"<has.no.tea@>',

'"MarvintheParanoidAndroid"<marv@>',

'the.mice@'];

//Usedinamethodcall.

goog.dom.createDom(goog.dom.TagName.DIV,{

id:'foo',

className:'some-css-class',

style:'display:none'

},'Hello,world!');比較長(zhǎng)的標(biāo)識(shí)符或者數(shù)值,不要為了讓代碼好看些而手工對(duì)齊.如:

CORRECT_Ototype={

a:0,

b:1,

lengthyName:2

};不要這樣做:

WRONG_Ototype={

a:0,

b:1,

lengthyName:2

};C.函數(shù)參數(shù)盡量讓函數(shù)參數(shù)在同一行上.如果一行超過(guò)80字符,每個(gè)參數(shù)獨(dú)占一行,并以4個(gè)空格縮進(jìn),或者與括號(hào)對(duì)齊,以提高可讀性.盡可能不要讓每行超過(guò)80個(gè)字符.比如下面這樣:

//Four-space,wrapat80.Workswithverylongfunctionnames,survives

//renamingwithoutreindenting,lowonspace.

goog.foo.bar.doThingThatIsVeryDifficultToExplain=function(

veryDescriptiveArgumentNumberOne,veryDescriptiveArgumentTwo,

tableModelEventHandlerProxy,artichokeDescriptorAdapterIterator){

//...

};

//Four-space,oneargumentperline.Workswithlongfunctionnames,

//survivesrenaming,andemphasizeseachargument.

goog.foo.bar.doThingThatIsVeryDifficultToExplain=function(

veryDescriptiveArgumentNumberOne,

veryDescriptiveArgumentTwo,

tableModelEventHandlerProxy,

artichokeDescriptorAdapterIterator){

//...

};

//Parenthesis-alignedindentation,wrapat80.Visuallygroupsarguments,

//lowonspace.

functionfoo(veryDescriptiveArgumentNumberOne,veryDescriptiveArgumentTwo,

tableModelEventHandlerProxy,artichokeDescriptorAdapterIterator){

//...

}

//Parenthesis-aligned,oneargumentperline.Visuallygroupsand

//emphasizeseachindividualargument.

functionbar(veryDescriptiveArgumentNumberOne,

veryDescriptiveArgumentTwo,

tableModelEventHandlerProxy,

artichokeDescriptorAdapterIterator){

//...

}D.傳遞匿名函數(shù)

如果參數(shù)中有匿名函數(shù),函數(shù)體從調(diào)用該函數(shù)的左邊開(kāi)始縮進(jìn)2個(gè)空格,而不是從function這個(gè)關(guān)鍵字開(kāi)始.這讓匿名函數(shù)更加易讀(不要增加很多沒(méi)必要的縮進(jìn)讓函數(shù)體顯示在屏幕的右側(cè)).varnames=items.map(function(item){

return;

});

prefix.something.reallyLongFunctionName('whatever',function(a1,a2){

if(a1.equals(a2)){

someOtherLongFunctionName(a1);

}else{

andNowForSomethingCompletelyDifferent(a2.parrot);

}

});E.更多的縮進(jìn)事實(shí)上,除了初始化數(shù)組和對(duì)象,和傳遞匿名函數(shù)外,所有被拆開(kāi)的多行文本要么選擇與之前的表達(dá)式左對(duì)齊,要么以4個(gè)(而不是2個(gè))空格作為一縮進(jìn)層次.

someWonderfulHtml=''+

getEvenMoreHtml(someReallyInterestingValues,moreValues,

evenMoreParams,'aduck',true,72,

slightlyMoreMonkeys(0xfff))+

'';

thisIsAVeryLongVariableName=

hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();

thisIsAVeryLongVariableName='expressionPartOne'+someMethodThatIsLong()+

thisIsAnEvenLongerOtherFunctionNameThatCannotBeIndentedMore();

someValue=this.foo(

shortArg,

'Somereallylongstringarg-thisisaprettycommoncase,actually.',

shorty2,

this.bar());

if(searchableCollection(allYourStuff).contains(theStuffYouWant)&&

!ambientNotification.isActive()&&(client.isAmbientSupported()||

client.alwaysTryAmbientAnyways()){

ambientNotification.activate();

}F.空行使用空行來(lái)劃分一組邏輯上相關(guān)聯(lián)的代碼片段.

doSomethingTo(x);

doSomethingElseTo(x);

andThen(x);

nowDoSomethingWith(y);

andNowWith(z);G.二元和三元操作符操作符始終跟隨著前行,這樣就不用顧慮分號(hào)的隱式插入問(wèn)題.如果一行實(shí)在放不下,還是按照上述的縮進(jìn)風(fēng)格來(lái)?yè)Q行.varx=a?b:c;//Allononelineifitwillfit.

//Indentation+4isOK.

vary=a?

longButSimpleOperandB:longButSimpleOperandC;

//IndentingtothelinepositionofthefirstoperandisalsoOK.

varz=a?

moreComplicatedB:

moreComplicatedC;6.括號(hào)只在需要的時(shí)候使用不要濫用括號(hào),只在必要的時(shí)候使用它.對(duì)于一元操作符(如delete,typeof和void),或是在某些關(guān)鍵詞(如return,throw,case,new)之后,不要使用括號(hào).7.字符串使用'優(yōu)于"單引號(hào)(')優(yōu)于雙引號(hào)(").當(dāng)你創(chuàng)建一個(gè)包含HTML代碼的字符串時(shí)就知道它的好處了.varmsg='ThisissomeHTML';8.可見(jiàn)性(私有域和保護(hù)域)推薦使用JSDoc中的兩個(gè)標(biāo)記:@private和@protectedJSDoc的兩個(gè)標(biāo)記@private和@protected用來(lái)指明類(lèi),函數(shù),屬性的可見(jiàn)性域.標(biāo)記為@private的全局變量和函數(shù),表示它們只能在當(dāng)前文件中訪問(wèn).標(biāo)記為@private的構(gòu)造器,表示該類(lèi)只能在當(dāng)前文件或是其靜態(tài)/普通成員中實(shí)例化;私有構(gòu)造器的公共靜態(tài)屬性在當(dāng)前文件的任何地方都可訪問(wèn),通過(guò)instanceof操作符也可.永遠(yuǎn)不要為全局變量,函數(shù),構(gòu)造器加@protected標(biāo)記.//File1.

//AA_PrivateClass_andAA_init_areaccessiblebecausetheyareglobal

//andinthesamefile.

/**

*@private

*@constructor

*/

AA_PrivateClass_=function(){

};

/**@private*/

functionAA_init_(){

returnnewAA_PrivateClass_();

}

AA_init_();

標(biāo)記為@private的屬性,在當(dāng)前文件中可訪問(wèn)它;如果是類(lèi)屬性私有,"擁有"該屬性的類(lèi)的所有靜態(tài)/普通成員也可訪問(wèn),但它們不能被不同文件中的子類(lèi)訪問(wèn)或覆蓋.標(biāo)記為@protected的屬性,在當(dāng)前文件中可訪問(wèn)它,如果是類(lèi)屬性保護(hù),那么"擁有"該屬性的類(lèi)及其子類(lèi)中的所有靜態(tài)/普通成員也可訪問(wèn).注意:這與C+,Java中的私有和保護(hù)不同,它們是在當(dāng)前文件中,檢查是否具有訪問(wèn)私有/保護(hù)屬性的權(quán)限,有權(quán)限即可訪問(wèn),而不是只能在同一個(gè)類(lèi)或類(lèi)層次上.而C+中的私有屬性不能被子類(lèi)覆蓋.(C++/Java中的私有/保護(hù)是指作用域上的可訪問(wèn)性,在可訪問(wèn)性上的限制.JS中是在限制在作用域上.PS:可見(jiàn)性是與作用域?qū)?yīng))

//File1.

/**@constructor*/

AA_PublicClass=function(){

};

/**@private*/

AA_PublicClass.staticPrivateProp_=1;

/**@private*/

AA_PublicCtotype.privateProp_=2;

/**@protected*/

AA_PublicClass.staticProtectedProp=31;

/**@protected*/

AA_PublicCtectedProp=4;

//File2.

/**

*@return{number}Thenumberofduckswe'vearrangedinarow.

*/

AA_PublicCtotype.method=function(){

//Legalaccessesofthesetwoproperties.

returnthis.privateProp_+AA_PublicClass.staticPrivateProp_;

};

//File3.

/**

*@constructor

*@extends{AA_PublicClass}

*/

AA_SubClass=function(){

//Legalaccessofaprotectedstaticproperty.

AA_PublicClass.staticProtectedProp=this.method();

};

goog.inherits(AA_SubClass,AA_PublicClass);

/**

*@return{number}Thenumberofduckswe'vearrangedinarow.

*/

AA_SubCtotype.method=function(){

//Legalaccessofaprotectedinstanceproperty.

returntectedProp;

};9.JavaScript類(lèi)型強(qiáng)烈建議你去使用編譯器.如果使用JSDoc,那么盡量具體地,準(zhǔn)確地根據(jù)它的規(guī)則來(lái)書(shū)寫(xiě)類(lèi)型說(shuō)明.目前支持兩種JS2和JS1.x類(lèi)型規(guī)范.JavaScript類(lèi)型語(yǔ)言JS2提議中包含了一種描述JavaScript類(lèi)型的規(guī)范語(yǔ)法,這里我們?cè)贘SDoc中采用其來(lái)描述函數(shù)參數(shù)和返回值的類(lèi)型.JSDoc的類(lèi)型語(yǔ)言,按照J(rèn)S2規(guī)范,也進(jìn)行了適當(dāng)改變,但編譯器仍然支持舊語(yǔ)法.

名稱(chēng)語(yǔ)法描述棄用語(yǔ)法普通類(lèi)型{boolean},{Window},{goog.ui.Menu}普通類(lèi)型的描述方法.

復(fù)雜類(lèi)型{Array.<string>}

字符串?dāng)?shù)組.{Object.<string,number>}

鍵為字符串,值為整數(shù)的對(duì)象類(lèi)型.參數(shù)化類(lèi)型,即指定了該類(lèi)型中包含的一系列"類(lèi)型參數(shù)".類(lèi)似于Java中的泛型.

聯(lián)合類(lèi)型{(number|boolean)}

一個(gè)整數(shù)或者布爾值.表示其值可能是A類(lèi)型,也可能是B類(lèi)型{(number,boolean)},{number|boolean},{(number||boolean)}記錄類(lèi)型myNum:number,myObject

由現(xiàn)有類(lèi)型組成的類(lèi)型.表示包含指定成員及類(lèi)型的值.這個(gè)例子中,myNum為number類(lèi)型,myObject為任意類(lèi)型.

注意大括號(hào)為類(lèi)型語(yǔ)法的一部分.比如,Array.<{length}>,表示一具有l(wèi)ength屬性的Array對(duì)象.

可為空類(lèi)型{?number}

一個(gè)整型數(shù)或者為NULL表示一個(gè)值可能是A類(lèi)型或者null.默認(rèn),每個(gè)對(duì)象都是可為空的.注意:函數(shù)類(lèi)型不可為空.{number?}非空類(lèi)型{!Object}

一個(gè)對(duì)象,但絕不會(huì)是null值.說(shuō)明一個(gè)值是類(lèi)型A且肯定不是null.默認(rèn)情況下,所有值類(lèi)型(boolean,number,string,和undefined)不可為空.{Object!}函數(shù)類(lèi)型{function(string,boolean)}

具有兩個(gè)參數(shù)(string和boolean)的函數(shù)類(lèi)型,返回值未知.說(shuō)明一個(gè)函數(shù).

函數(shù)返回類(lèi)型{function():number}

函數(shù)返回一個(gè)整數(shù).說(shuō)明函數(shù)的返回類(lèi)型.

函數(shù)的this類(lèi)型{function(this:goog.ui.Menu,string)}

函數(shù)只帶一個(gè)參數(shù)(string),并且在上下文goog.ui.Menu中執(zhí)行.說(shuō)明函數(shù)類(lèi)型的上下文類(lèi)型.

可變參數(shù){function(string,...[number]):number}

帶一個(gè)參數(shù)(字符類(lèi)型)的函數(shù)類(lèi)型,并且函數(shù)的參數(shù)個(gè)數(shù)可變,但參數(shù)類(lèi)型必須為number.說(shuō)明函數(shù)的可變長(zhǎng)參數(shù).

可變長(zhǎng)的參數(shù)(使用@param標(biāo)記)@param{...number}var_args

函數(shù)參數(shù)個(gè)數(shù)可變.使用標(biāo)記,說(shuō)明函數(shù)具有不定長(zhǎng)參數(shù).

函數(shù)的缺省參數(shù){function(?string=,number=)}

函數(shù)帶一個(gè)可空且可選的字符串型參數(shù),一個(gè)可選整型參數(shù).=語(yǔ)法只針對(duì)function類(lèi)型有效.說(shuō)明函數(shù)的可選參數(shù).

函數(shù)可選參數(shù)(使用@param標(biāo)記)@param{number=}opt_argument

number類(lèi)型的可選參數(shù).使用標(biāo)記,說(shuō)明函數(shù)具有可選參數(shù).

所有類(lèi)型{*}表示變量可以是任何類(lèi)型.

JavaScript中的類(lèi)型

類(lèi)型示例值示例描述number1

1.0

-5

1e5

Math.PI

NumbernewNumber(true)Number對(duì)象string'Hello'

"World"

String(42)字符串值StringnewString('Hello')

newString(42)字符串對(duì)象booleantrue

false

Boolean(0)布爾值BooleannewBoolean(true)布爾對(duì)象RegExpnewRegExp('hello')

/world/g

DatenewDate

newDate()

nullnull

undefinedundefined

voidfunctionf(){

return;

}沒(méi)有返回值A(chǔ)rray['foo',0.3,null]

[]類(lèi)型不明確的數(shù)組Array.<number>[11,22,33]整型數(shù)組Array.<Array.<string>>[['one','two','three'],['foo','bar']]字符串?dāng)?shù)組的數(shù)組Object{}

{foo:'abc',bar:123,baz:null}

Object.<string>{'foo':'bar'}值為字符串的對(duì)象.Object.<number,string>varobj={};

obj[1]='bar';鍵為整數(shù),值為字符串的對(duì)象.注意,JavaScript中,鍵總是被轉(zhuǎn)換成字符串,所以obj['1']==obj[1].也所以,鍵在for...in循環(huán)中是字符串類(lèi)型.但在編譯器中會(huì)明確根據(jù)鍵的類(lèi)型來(lái)查找對(duì)象.Functionfunction(x,y){

returnx*y;

}函數(shù)對(duì)象function(number,number):numberfunction(x,y){

returnx*y;

}函數(shù)值SomeClass/**@constructor*/

functionSomeClass(){}

newSomeClass();

SomeInterface/**@interface*/

functionSomeInterface(){}

SomeItotype.draw=function(){};

project.MyClass/**@constructor*/

project.MyClass=function(){}

newproject.MyClass()

project.MyEnum/**@enum{string}*/

project.MyEnum={

BLUE:'#0000dd',

RED:'#dd0000'

};枚舉Elementdocument.createElement('div')DOM中的元素Nodedocument.body.firstChildDOM中的節(jié)點(diǎn).HTMLInputElementhtmlDocument.getElementsByTagName('input')[0]DOM中,特定類(lèi)型的元可空vs.可選參數(shù)和屬性

JavaScript是一種弱類(lèi)型語(yǔ)言,明白可選,非空和未定義參數(shù)或?qū)傩灾g的細(xì)微差別還是很重要的.

對(duì)象類(lèi)型(引用類(lèi)型)默認(rèn)非空.注意:函數(shù)類(lèi)型默認(rèn)不能為空.除了字符串,整型,布爾,undefined和null外,對(duì)象可以是任何類(lèi)型.

/**

*Someclass,initializedwithavalue.

*@param{Object}valueSomevalue.

*@constructor

*/

functionMyClass(value){

/**

*Somevalue.

*@type{Object}

*@private

*/

this.myValue_=value;

}

告訴編譯器myValue_屬性為一對(duì)象或null.如果myValue_永遠(yuǎn)都不會(huì)為null,就應(yīng)該如下聲明:

/**

*Someclass,initializedwithanon-nullvalue.

*@param{!Object}valueSomevalue.

*@constructor

*/

functionMyClass(value){

/**

*Somevalue.

*@type{!Object}

*@private

*/

this.myValue_=value;

}

這樣,當(dāng)編譯器在代碼中碰到MyClass為null時(shí),就會(huì)給出警告.函數(shù)的可選參數(shù)可能在運(yùn)行時(shí)沒(méi)有定義,所以如果他們又被賦給類(lèi)屬性,需要聲明成:

/**

*Someclass,initializedwithanoptionalvalue.

*@param{Object=}opt_valueSomevalue(optional).

*@constructor

*/

functionMyClass(opt_value){

/**

*Somevalue.

*@type{Object|undefined}

*@private

*/

this.myValue_=opt_value;

}

這告訴編譯器myValue_可能是一個(gè)對(duì)象,或null,或undefined.

注意:可選參數(shù)opt_value被聲明成{Object=},而不是{Object|undefined}.這是因?yàn)榭蛇x參數(shù)可能是undefined.雖然直接寫(xiě)undefined也并無(wú)害處,但鑒于可閱讀性還是寫(xiě)成上述的樣子.

最后,屬性的非空和可選并不矛盾,屬性既可是非空,也可是可選的.下面的四種聲明各不相同:

/**

*Takesfourarguments,twoofwhicharenullable,andtwoofwhichare

*optional.

*@param{!Object}nonNullMandatory(mustnotbeundefined),mustnotbenull.

*@param{Object}mayBeNullMandatory(mustnotbeundefined),maybenull.

*@param{!Object=}opt_nonNullOptional(maybeundefined),butifpresent,

*mustnotbenull!

*@param{Object=}opt_mayBeNullOptional(maybeundefined),maybenull.

*/

functionstrangeButTrue(nonNull,mayBeNull,opt_nonNull,opt_mayBeNull){

//...

};10.注釋A.使用JSDoc

我們使用JSDoc中的注釋風(fēng)格.行內(nèi)注釋使用//變量的形式.另外,我們也遵循C++代碼注釋風(fēng)格.這也就是說(shuō)你需要:版權(quán)和著作權(quán)的信息,文件注釋中應(yīng)該寫(xiě)明該文件的基本信息(如,這段代碼的功能摘要,如何使用,與哪些東西相關(guān)),來(lái)告訴那些不熟悉代碼的讀者.類(lèi),函數(shù),變量和必要的注釋,期望在哪些瀏覽器中執(zhí)行,正確的大小寫(xiě),標(biāo)點(diǎn)和拼寫(xiě).

為了避免出現(xiàn)句子片段,請(qǐng)以合適的大/小寫(xiě)單詞開(kāi)頭,并以合適的標(biāo)點(diǎn)符號(hào)結(jié)束這個(gè)句子.現(xiàn)在假設(shè)維護(hù)這段代碼的是一位初學(xué)者.這可能正好是這樣的!目前很多編譯器可從JSDoc中提取類(lèi)型信息,來(lái)對(duì)代碼進(jìn)行驗(yàn)證,刪除和壓縮.因此,你很有必要去熟悉正確完整的JSDoc.B.頂層/文件注釋

頂層注釋用于告訴不熟悉這段代碼的讀者這個(gè)文件中包含哪些東西.應(yīng)該提供文件的大體內(nèi)容,它的作者,依賴(lài)關(guān)系和兼容性信息.如下:

//Copyright2009GoogleInc.AllRightsReserved.

/**

*@Descriptionoffile,itsusesandinformation

*aboutitsdependencies.

*@authoruser@(FirstnameLastname)

*/C.類(lèi)注釋每個(gè)類(lèi)的定義都要附帶一份注釋,描述類(lèi)的功能和用法.也需要說(shuō)明構(gòu)造器參數(shù).如果該類(lèi)繼承自其它類(lèi),應(yīng)該使用@extends標(biāo)記.如果該類(lèi)是對(duì)接口的實(shí)現(xiàn),應(yīng)該使用@implements標(biāo)記.

/**

*Classmakingsomethingfunandeasy.

*@param{string}arg1Anargumentthatmakesthismoreinteresting.

*@param{Array.<number>}arg2Listofnumberstobeprocessed.

*@constructor

*@extends{goog.Disposable}

*/

project.MyClass=function(arg1,arg2){

//...

};

goog.inherits(project.MyClass,goog.Disposable);方法與函數(shù)的注釋.提供參數(shù)的說(shuō)明.使用完整的句子,并用第三人稱(chēng)來(lái)書(shū)寫(xiě)方法說(shuō)明.

/**

*Convertstexttosomecompletelydifferenttext.

*@param{string}arg1Anargumentthatmakesthismoreinteresting.

*@return{string}Somereturnvalue.

*/

project.MyCtotype.someMethod=function(arg1){

//...

};

/**

*OperatesonaninstanceofMyClassandreturnssomething.

*@param{project.MyClass}objInstanceofMyClasswhichleadstoalong

*commentthatneedstobewrappedtotwolines.

*@return{boolean}Whethersomethingoccured.

*/

functionPR_someMethod(obj){

//...

}對(duì)于一些簡(jiǎn)單的,不帶參數(shù)的getters,說(shuō)明可以忽略.

/**

*@return{Element}Theelementforthecomponent.

*/

goog.ui.Ctotype.getElement=function(){

returnthis.element_;

};D.屬性注釋

需要對(duì)屬性進(jìn)行注釋.

/**

*Maximumnumberofthingsperpane.

*@type{number}

*/

project.MyCtotype.someProperty=4;E.類(lèi)型轉(zhuǎn)換的注釋有時(shí),類(lèi)型檢查不能很準(zhǔn)確地推斷出表達(dá)式的類(lèi)型,所以應(yīng)該給它添加類(lèi)型標(biāo)記注釋來(lái)明確之,并且必須在表達(dá)式和類(lèi)型標(biāo)簽外面包裹括號(hào).

/**@type{number}*/(x)

(/**@type{number}*/x)F.JSDoc縮進(jìn)如果你在@param,@return,@supported,@this或@deprecated中斷行,需要像在代碼中一樣,使用4個(gè)空格作為一個(gè)縮進(jìn)層次.

/**

*Illustrateslinewrappingforlongparam/returndescriptions.

*@param{string}fooThisisaparamwithadescriptiontoolongtofitin

*

oneline.

*@return{number}Thisreturnssomethingthathasadescriptiontoolongto

*

fitinoneline.

*/

project.MyCtotype.method=function(foo){

return5;

};不要在@標(biāo)記中進(jìn)行縮進(jìn).雖然不建議,但也可對(duì)說(shuō)明文字進(jìn)行適當(dāng)?shù)呐虐鎸?duì)齊.不過(guò),這樣帶來(lái)一些負(fù)面影響,就是當(dāng)你每次修改變量名時(shí),都得重新排版說(shuō)明文字以保持和變量名對(duì)齊./**

*ThisisNOTthepreferredindentationmethod.

*@param{string}fooThisisaparamwithadescriptiontoolongtofitin

*

oneline.

*@return{number}Thisreturnssomethingthathasadescriptiontoolongto

*

fitinoneline.

*/

project.MyCtotype.method=function(foo){

return5;

};枚舉/**

*Enumfortri-statevalues.

*@enum{number}

*/

project.TriState={

TRUE:1,

FALSE:-1,

MAYBE:0

};

注意一下,枚舉也具有有效類(lèi)型,所以可以當(dāng)成參數(shù)類(lèi)型來(lái)用.

/**

*Setsprojectstate.

*@param{project.TriState}stateNewprojectstate.

*/

project.setState=function(state){

//...

};G.Typedefs有時(shí)類(lèi)型會(huì)很復(fù)雜.比如下面的函數(shù),接收Element參數(shù):

/**

*@param{string}tagName

*@param{(string|Element|Text|Array.<Element>|Array.<Text>)}contents

*@return{Element}

*/

goog.createElement=function(tagName,contents){

...

};

你可以使用@typedef標(biāo)記來(lái)定義個(gè)常用的類(lèi)型表達(dá)式.

/**@typedef{(string|Element|Text|Array.<Element>|Array.<Text>)}*/

goog.ElementContent;

/**

*@param{string}tagName

*@param{goog.ElementContent}contents

*@return{Element}

*/

goog.createElement=function(tagName,contents){

...

};H.JSDoc標(biāo)記表標(biāo)記模板&例子描述類(lèi)型檢測(cè)支持@param@param{Type}變量名描述如:/**

*QueriesaBazforitems.

*@param{number}groupNumSubgroupidtoquery.

*@param{string|number|null}termAnitemName,

*oritemId,ornulltosearcheverything.

*/

goog.Btotype.query=function(groupNum,term){

//...

};給方法,函數(shù),構(gòu)造器中的參數(shù)添加說(shuō)明.完全支持.@return@return{Type}描述如:/**

*@return{string}ThehexIDofthelastitem.

*/

goog.Btotype.getLastId=function(){

//...

returnid;

};給方法,函數(shù)的返回值添加說(shuō)明.在描述布爾型參數(shù)時(shí),用"Whetherthecomponentisvisible"這種描述優(yōu)于"Trueifthecomponentisvisible,falseotherwise".如果函數(shù)沒(méi)有返回值,就不需要添加@return標(biāo)記.完全支持.@author@authorusername@(firstlast)如:/**

*@Utilitiesforhandlingtextareas.

*@authorkuth@(UthurPendragon)

*/表明文件的作者,通常僅會(huì)在@注釋中使用到它.不需要.@see@seeLink如:/**

*Addsasingleitem,recklessly.

*@see#addSafely

*@seegoog.Collect

*@seegoog.RecklessAdder#add

...給出引用鏈接,用于進(jìn)一步查看函數(shù)/方法的相關(guān)細(xì)節(jié).不需要.@@描述如:/**

*@Utilitiesfordoingthingsthatrequirethisverylong

*butnotindentedcomment.

*@authorkuth@(UthurPendragon)

*/文件通覽.不需要.@constructor@constructor如:/**

*Arectangle.

*@constructor

*/

functionGM_Rect(){

...

}指明類(lèi)中的構(gòu)造器.會(huì)檢查.如果省略了,編譯器將禁止實(shí)例化.@interface@interface如:/**

*Ashape.

*@interface

*/

functionShape(){};

Stotype.draw=function(){};

/**

*Apolygon.

*@interface

*@extends{Shape}

*/

functionPolygon(){};

Ptotype.getSides=function(){};指明這個(gè)函數(shù)是一個(gè)接口.會(huì)檢查.如果實(shí)例化一個(gè)接口,編譯器會(huì)警告.@type@typeType

@type{Type}如:/**

*ThemessagehexID.

*@type{string}

*/

varhexId=hexId;標(biāo)識(shí)變量,屬性或表達(dá)式的類(lèi)型.大多數(shù)類(lèi)型是不需要加大括號(hào)的,但為了保持一致,建議統(tǒng)一加大括號(hào).會(huì)檢查@extends@extendsType

@extends{Type}如:/**

*Immutableemptynodelist.

*@constructor

*@extendsgoog.ds.BasicNodeList

*/

goog.ds.EmptyNodeList=function(){

...

};與@constructor一起使用,用來(lái)表明該類(lèi)是擴(kuò)展自其它類(lèi)的.類(lèi)型外的大括號(hào)可寫(xiě)可不寫(xiě).會(huì)檢查@implements@implementsType

@implements{Type}如:/**

*Ashape.

*@interface

*/

functionShape(){};

Stotype.draw=function(){};

/**

*@constructor

*@implements{Shape}

*/

functionSquare(){};

Stotype.draw=function(){

...

};與@constructor一起使用,用來(lái)表明該類(lèi)實(shí)現(xiàn)自一個(gè)接口.類(lèi)型外的大括號(hào)可寫(xiě)可不寫(xiě).會(huì)檢查.如果接口不完整,編譯器會(huì)警告.@lends@lendsobjectName

@lends{objectName}如:goog.object.extend(

Btotype,

/**@lends{Btotype}*/

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論