版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 假如和建筑合同
- 新在線客服個(gè)人年終總結(jié)
- 公司勞務(wù)用工合同模板2024
- 農(nóng)副業(yè)承包合同范本
- 廣告委托加工宣傳發(fā)布合同
- 建設(shè)工程施工勞務(wù)分包合同
- 高中班主任德育年度個(gè)人工作總結(jié)
- 貴州城市職業(yè)學(xué)院《機(jī)械設(shè)計(jì)》2023-2024學(xué)年第一學(xué)期期末試卷
- 貴陽(yáng)職業(yè)技術(shù)學(xué)院《數(shù)據(jù)科學(xué)導(dǎo)論》2023-2024學(xué)年第一學(xué)期期末試卷
- 油橄欖示范基地建設(shè)項(xiàng)目可行性研究報(bào)告-油橄欖市場(chǎng)需求持續(xù)擴(kuò)大
- 滯銷(xiāo)風(fēng)險(xiǎn)管理制度內(nèi)容
- 關(guān)于物業(yè)服務(wù)意識(shí)的培訓(xùn)
- JJF 2184-2025電子計(jì)價(jià)秤型式評(píng)價(jià)大綱(試行)
- 排污許可證辦理合同1(2025年)
- GB/T 44890-2024行政許可工作規(guī)范
- 上??颇恳豢荚囶}庫(kù)參考資料1500題-上海市地方題庫(kù)-0
- 【7地XJ期末】安徽省宣城市寧國(guó)市2023-2024學(xué)年七年級(jí)上學(xué)期期末考試地理試題(含解析)
- 設(shè)備操作、保養(yǎng)和維修規(guī)定(4篇)
- (完整版)四年級(jí)上冊(cè)數(shù)學(xué)豎式計(jì)算題100題直接打印版
- 玻璃瓶罐的缺陷產(chǎn)生原因及解決方法63699
- 高層住宅(23-33層)造價(jià)估算指標(biāo)
評(píng)論
0/150
提交評(píng)論