【經(jīng)驗(yàn)總結(jié)】編寫JavaScript代碼時(shí)應(yīng)遵循的14條規(guī)律
本文講述了編寫JavaScript代碼時(shí)應(yīng)遵循的14條規(guī)律。分享給大家供大家參考,具體如下:
1. 總是使用 ‘var'
在javascript中,變量不是全局范圍的就是函數(shù)范圍的,使用”var”關(guān)鍵詞將是保持變量簡潔明了的關(guān)鍵。當(dāng)聲明一個(gè)或者是全局或者是函數(shù)級(jí)(function-level)的變量,需總是前置”var”關(guān)鍵詞,下面的例子將強(qiáng)調(diào)不這樣做潛在的問題。
不使用 Var 造成的問題
var i=0; // This is good - creates a global variable function test() { for (i=0; i<10; i++) { alert("Hello World!"); } } test(); alert(i); // The global variable i is now 10!
因?yàn)樽兞亢瘮?shù)中變量 i 并沒有使用 var 使其成為函數(shù)級(jí)的變量,在這個(gè)例子中它引用了全局變量??偸鞘褂?var 來聲明全局變量是一個(gè)很多的做法,但至關(guān)重要的一點(diǎn)是使用 var 定義一個(gè)函數(shù)范圍的變量。下面這兩個(gè)方法在功能上是相同的:
正確的函數(shù)
function test() { var i=0; for (i=0;i<10; i++) { alert("Hello World!"); } }
正確的函數(shù)
function test() { for (var i=0; i<10; i++) { alert("Hello World!"); } }
2. 特性檢測而非瀏覽器檢測
一些代碼是寫來發(fā)現(xiàn)瀏覽器版本并基于用戶正使用的客戶端的對(duì)其執(zhí)行不同行為。這個(gè),總的來說,是一個(gè)非常糟的實(shí)踐。更好的方法是使用特性檢測,在使 用一個(gè)老瀏覽器可能不支持的高級(jí)的特性之前,首先檢測(瀏覽器的)是否有這個(gè)功能或特性,然后使用它。這單獨(dú)檢測瀏覽器版本來得更好,即使你知道它的性 能。你可以在 http://www.jibbering.com/faq/faq_notes/not_browser_detect.html找到一個(gè)深入討論這個(gè)問題的文章。
例子:
if (document.getElementById) { var element = document.getElementById('MyId'); } else { alert('Your browser lacks the capabilities required to run this script!'); }
3. 使用方括號(hào)記法
當(dāng)訪問由執(zhí)行時(shí)決定或者包括要不能用”.”號(hào)訪問的對(duì)象屬性,使用方括號(hào)記法。如果你不是一個(gè)經(jīng)驗(yàn)豐富的Javascript程序員,總是使用方括號(hào)是一個(gè)不錯(cuò)的做法
對(duì)象的屬性由兩種固定的方法來訪問:”.”記法和”[ ]“方括號(hào)記法:
“.”號(hào)記法:
MyObject.property
“[ ]“方括號(hào)記法:
MyObject["property"]
使用”.”號(hào),屬性名是硬代碼,不能在執(zhí)行時(shí)改變。使用”[ ]“方括號(hào),屬性名是一個(gè)通過計(jì)算屬性名而來的字符串。字符串要以是硬代碼,也可能是變量,甚至可以是一個(gè)調(diào)回一個(gè)字母串值的函數(shù)。 如果一個(gè)屬性名在執(zhí)行產(chǎn)生,方括號(hào)是必須,如果你有 “value1″, “value2″, 和 “value3″這樣的屬性,并且想利用變量 i=2來訪問
這個(gè)可以運(yùn)行:
MyObject["value"+i]
這個(gè)不可以:
MyObject.value+i
并且在某些服務(wù)器端環(huán)境(PHP、Struts等)下,F(xiàn)orm 表單被附加了 [ ] 號(hào)來表示 Form 表單在服務(wù)器端必須被當(dāng)作數(shù)組來對(duì)待。如此,用”.”號(hào)來引用一個(gè)包含 [ ] 號(hào)的字段將不會(huì)執(zhí)行,因?yàn)?[ ] 是引用一個(gè) Javascript 數(shù)組的語法。所以,[ ] 號(hào)記法是必須的:
這個(gè)可以運(yùn)行:
formref.elements["name[]"]
這個(gè)不可以:
formref.elements.name[]
推薦使用”[ ]“方括號(hào)記法是說當(dāng)其需要時(shí)(明顯地)總是使用它。當(dāng)不是嚴(yán)格需要使用它的時(shí)候,它是一個(gè)私人的偏好和習(xí)慣。一個(gè)好的經(jīng)驗(yàn)原則是,使用”.”號(hào)記法訪問標(biāo)準(zhǔn)的對(duì)象屬性,使用”[ ]“方括號(hào)記法訪問由頁面定義的對(duì)象屬性。這樣,document["getElementById"]() 是一個(gè)完美可行的”[ ]“方括號(hào)記法用法,但 document.getElementById() 在語法上是首選,因?yàn)?getElementById 是一個(gè) DOM 規(guī)范中定義的一個(gè)標(biāo)準(zhǔn)文檔對(duì)象屬性?;旌鲜褂眠@兩個(gè)記法使哪個(gè)是標(biāo)準(zhǔn)對(duì)象屬性,哪個(gè)屬性名是由上下文所定義的,在代碼中顯得清晰明了:
document.forms["myformname"].elements["myinput"].value
這里,forms 是 document 的一個(gè)標(biāo)準(zhǔn)屬性,而表單名 myformname 則是由頁面所定義的。同時(shí),elements 和 value 屬性都是由規(guī)范所定義的標(biāo)準(zhǔn)屬性。而 myinput 則是由頁面所定義的。這頁是句法讓人非常容易理解(代碼的內(nèi)容),是一個(gè)推薦遵循的習(xí)慣用法,但不是嚴(yán)格原則。
4. 避免 ‘eval'
在Javascript中,eval()功能是一個(gè)在執(zhí)行期中執(zhí)行任意代碼的方法。在幾乎所有的情況下,eval 都不應(yīng)該被使用。如果它出現(xiàn)在你的頁面中,則表明你所做的有更好的方法。舉一個(gè)例子,eval 通常被不知道要使用方括號(hào)記法的程序員所使用。
原則上,”Eval is evil(Eval是魔鬼)”。別使用它,除非你是一個(gè)經(jīng)驗(yàn)豐富的開發(fā)者并且知道你的情況是個(gè)例外。
5. 正確地引用表單和表單元素
所有的 html 表單都應(yīng)該有一個(gè) name 屬性。對(duì)于 XHTML 文檔來說,name 屬性是不被要求的,但 Form 標(biāo)簽中應(yīng)有相應(yīng)有 id 屬性,并必須用 document.getElementById() 來引用。使用像 document.forms[0] 這樣的索引方法來引用表單,在幾乎所有情況下,是一個(gè)糟糕的做法。有些瀏覽器把文檔中使用 form 來命名的元素當(dāng)作一個(gè)可用的 form 屬性。這樣并不可靠,不應(yīng)該使用。
下面這個(gè)例子用使用方括號(hào)和正確的對(duì)象引用方法來展示如何防止錯(cuò)誤地引用一個(gè)表單的input:
正確引用表單 Input:
document.forms["formname"].elements["inputname"]
糟糕的做法:
document.formname.inputname
如果你要引用一個(gè)函數(shù)里的兩個(gè)表單元素,較好的做法是先引用這個(gè)form對(duì)象,并將其儲(chǔ)存在變量中。這樣避免了重復(fù)查詢以解決表單的引用:
var formElements = document.forms["mainForm"].elements; formElements["input1"].value="a"; formElements["input2"].value="b";
當(dāng)你使用 onChange 或者其他類似的事件處理方法,一個(gè)好的做法是總是通過一個(gè)引來把 input 元素本身引用到函數(shù)中來。所有 input 元素都帶有一個(gè)對(duì)包含其在內(nèi)的Form表單有一個(gè)引用:
<input type="text" name="address" onChange="validate(this)">
function validate(input_obj) { // 引用包含這個(gè)元素的form var theform = input_obj.form; // 現(xiàn)在你可以不需要使用硬代碼來引用表單自身 if (theform.elements["city"].value=="") { alert("Error"); } }
通過對(duì)表單元素的引用來訪問表單的屬性,你可以寫一個(gè)不包含硬代碼的函數(shù)來引用這個(gè)頁面中任何一個(gè)有特定名的表單。這是一個(gè)非常好的做法,因?yàn)楹瘮?shù)變得可重用。
避免 ‘with'
Javascript 中的 with 聲明在一個(gè)作用域的前端插入一個(gè)對(duì)象,所以任何屬性/變量的引用將會(huì)倚著對(duì)象被首先解決。這通常被用作一個(gè)避免重復(fù)引用的快捷方法:
使用 with 的例子:
with (document.forms["mainForm"].elements) { input1.value = "junk"; input2.value = "junk"; }
但問題在于程序員并沒有方法來驗(yàn)證 input1 或 input2 實(shí)際上已經(jīng)被當(dāng)作 Form 元素?cái)?shù)組的屬性來解決。它首先會(huì)以這些name值來檢測屬性,如果找不到,它將會(huì)繼續(xù)(向下)檢測這個(gè)作用域。最后,它在全局對(duì)象中嘗試把input1 和 input2 作為一個(gè)全局對(duì)象來對(duì)待,而這以一個(gè)錯(cuò)誤作為結(jié)尾。
變通的方法是:創(chuàng)建一個(gè)引用來減少引用的對(duì)象,并使用它來解決這些引用。
使用一個(gè)引用:
var elements = document.forms["mainForm"].elements; elements.input1.value = "junk"; elements.input2.value = "junk";
7. 在錨點(diǎn)中使用 “onclick” 替代 “javascript: Pseudo-Protocol”
如果你想在 <a> 標(biāo)簽中觸發(fā)Javascript 代碼,選擇 onclick 而非 JavaScript: pseudo-protocol;使用 onclick 來運(yùn)行的 Javascript 代碼必須返回 ture 或者false(or an expression than evalues to true or false [這句要怎么翻譯呢? 我是這樣理解的:一個(gè)優(yōu)先性高于true 或 false 的表達(dá)式])來返回標(biāo)簽本身:如果返回 true,則錨點(diǎn)的 href 將被當(dāng)作一個(gè)一般的鏈接;如果返回 false,則 href 會(huì)被忽略。這就是為什么”return false;” 經(jīng)常被包含在 onclick 所處理代碼的尾部。
正確句法:
在這個(gè)實(shí)例中,”doSomething()” 函數(shù)(定義于頁面的某個(gè)角落)將在被點(diǎn)擊時(shí)調(diào)用。href 將永遠(yuǎn)不會(huì)被啟用了Javascript 的瀏覽器訪問。在你可以提醒Javascript 是必須的、而用戶未啟用之的瀏覽器中,文檔 javascript_required.html 才會(huì)被加載。通常,當(dāng)你確保用戶將會(huì)開啟 Javascript 支持,為盡量簡化,鏈接將只包含 href=”#”。 而這個(gè)做法是不被鼓勵(lì)的。通常有一個(gè)不錯(cuò)的做法是:可以提供沒用啟用 javascript 一個(gè)返回本地的頁面。
有時(shí),眾多想要分情況來訪問一個(gè)鏈接。例如,當(dāng)一個(gè)用戶要離開你的一個(gè)表單頁面,而想先驗(yàn)證來確保沒有東西被改變。在這個(gè)情況下,你的 onclick 將會(huì)訪問一個(gè)返回詢問鏈接是否應(yīng)該被遵循的函數(shù):
有條件的鏈接訪問:
<a href="/" onClick="return validate();">Home</a>
function validate() { return prompt("Are you sure you want to exit this page?"); }
在這個(gè)實(shí)例中,validate() 函數(shù)必須只返回 ture 或 false。ture 的時(shí)候用戶將被允許問題 home 頁面,或 false 的時(shí)候鏈接不被訪問。這個(gè)例子提示確認(rèn)(其行為),以訪問 ture 或 false,這完全由用戶點(diǎn)擊”確實(shí)”或者”取消”決定。
下面是一些”不應(yīng)該”的例子。如果你在自己的頁面中看到下面這樣的代碼,這是不正確的,需要被修改:
什么是不應(yīng)該做的:
<a href="javascript:doSomething()">link</a> <a href="http://www.dbjr.com.cn/#" onClick="doSomething()">link</a> <a href="http://www.dbjr.com.cn/#" onClick="javascript:doSomething();">link</a> <a href="http://www.dbjr.com.cn/#" onClick="javascript:doSomething(); return false;">link</a>
8. 使用一元 ‘+' 號(hào)運(yùn)算符使類型轉(zhuǎn)向Number
在Javascript中,”+”號(hào)運(yùn)算符同時(shí)充當(dāng)數(shù)學(xué)加號(hào)和連接符。這會(huì)在form表單的域值相加時(shí)出現(xiàn)問題,例如,因?yàn)镴avascript是 一個(gè)弱類型語言,form 域的值將會(huì)被當(dāng)作數(shù)組來處理,而你把它們”+”一起的時(shí)候,”+”將被當(dāng)成連接符,而非數(shù)學(xué)加號(hào)。
有問題的例子:
<form name="myform" action="[url]"> <input type="text" name="val1" value="1"> <input type="text" name="val2" value="2"> </form>
function total() { var theform = document.forms["myform"]; var total = theform.elements["val1"].value + theform.elements["val2"].value; alert(total); // 這個(gè)將會(huì)彈出 "12", 但你想要的是 3! }
解決這個(gè)問題,Javascript 需要一個(gè)提示來讓它把這些值當(dāng)做數(shù)字來處理。你可以使用”+”號(hào)來把數(shù)組轉(zhuǎn)換成數(shù)字。給變量或者表達(dá)式前置一個(gè)”+”號(hào)將會(huì)強(qiáng)制其當(dāng)作一個(gè)數(shù)字來處理,而這也將使得數(shù)學(xué)”+”得以成功應(yīng)用。
修改好的代碼:
function total() { var theform = document.forms["myform"]; var total = (+theform.elements["val1"].value) + (+theform.elements["val2"].value); alert(total); // This will alert 3 }
9. 避免 document.all
document.all 是由Microsoft 的 IE 所引進(jìn)的,并不是一個(gè)標(biāo)準(zhǔn)的 Javascript DOM 特性。盡管大多數(shù)新的瀏覽器支持它以支持依賴于它的糟糕代碼,(而)還有很多瀏覽器是不支持的。
并沒有理由其他方法都不適用,而一個(gè)老的IE瀏覽器(<5.0)需要支持,而在Javascript中使用 document.all 作為一個(gè)折衷方法。 你并不需要使用 document.all 來檢測其是不是IE瀏覽器,因?yàn)槠渌麨g覽器現(xiàn)在一般都支持。
只把 document.all 當(dāng)做最后的選擇:
if (document.getElementById) { var obj = document.getElementById("myId"); } else if (document.all) { var obj = document.all("myId"); }
一些使用 document.all 的原則:
同嘗試其他方法
當(dāng)其作為最后的選擇
當(dāng)需要支持 5.0 版本以下的 IE 瀏覽器
總是使用 “if (document.all) { }” 來查看是否支持.
10. 不要在腳本代碼塊中使用HTML注釋
在 Javascript 的舊日子(1995)里,諸如 Netscape 1.0 的一些瀏覽器并不支持或認(rèn)識(shí) <script> 標(biāo)簽。所以,當(dāng) Javascript 第一次被發(fā)布,需要有一個(gè)技術(shù)來讓實(shí)些代碼不被當(dāng)做文本顯示于舊版瀏覽器上。有一個(gè)”hack” 是在代碼中使用 HTML 注釋來隱藏這些代碼。
使 HTML 注釋并不好:
<script language="javascript"> <!-- // code here //--> </script>
在今天,沒有任何一個(gè)常用的瀏覽器會(huì)忽略掉 <script> 標(biāo)簽。因此,再?zèng)]必要隱藏 Javascript 源代碼。事實(shí)上,它還可以因?yàn)橄旅娴睦碛桑徽J(rèn)為是無益的:
在 XHTML 文檔中,源代碼將向所有瀏覽器隱藏并被渲染成無用的(內(nèi)容);
– 在 HTML 注釋并不允許 ,這個(gè)會(huì)讓任何遞減操作將失效。
11. 避免亂用全局命名空間
一般很少需要全部變量和函數(shù)。全局使用將可能導(dǎo)致 Javascript 源文件文檔沖突,和代碼中止。因此,一個(gè)好的做法是在一個(gè)全局命名空間內(nèi)采用函數(shù)性的封裝。有多個(gè)方法可以完成這個(gè)任務(wù),有此相對(duì)比較復(fù)雜。最簡單的方法 是創(chuàng)建一個(gè)全局對(duì)象,并把屬性和方法指派給這個(gè)對(duì)象:
創(chuàng)建一個(gè)命名空間:
var MyLib = {}; // global Object cointainer MyLib.value = 1; MyLib.increment = function() { MyLib.value++; } MyLib.show = function() { alert(MyLib.value); } MyLib.value=6; MyLib.increment(); MyLib.show(); // alerts 7
命名空間也可以使用 Closures(閉包?) 來創(chuàng)建,并且 Private Member Variables (私有變量?) 也可以偽裝于 Javascript中。
12. 避免同步的 ‘a(chǎn)jax' 調(diào)用
當(dāng)使用”Ajax”請(qǐng)求時(shí),你要么選擇異步模式,要么使用同步模式。當(dāng)瀏覽器行為可以繼續(xù)執(zhí)行,異步模式將請(qǐng)求放在后臺(tái)執(zhí)行,同步模式則會(huì)等待請(qǐng)求完成后才繼續(xù)。
應(yīng)該避免同步模式做出的請(qǐng)求。這些請(qǐng)求將會(huì)對(duì)用戶禁用瀏覽器,直至請(qǐng)求返回。一旦服務(wù)器忙,并需要一段時(shí)間來完成請(qǐng)求,用戶的瀏覽器(或者 OS)將不能做任何其他的事,直至請(qǐng)求超時(shí)。
如果你覺得自己的情況需要同步模式,最大的可能是你需要時(shí)間來重新想一下你的設(shè)計(jì)。很少(如果有的話)實(shí)際上需要同步模式的 Ajax 請(qǐng)求。
13. 使用 JSON
當(dāng)需要將數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)成純文本,或者通過 Ajax 發(fā)送/取回?cái)?shù)據(jù)結(jié)構(gòu),盡可能使用 JSON 代替 XML。JSON (JavaScript Object Notation) 是一個(gè)更簡潔有效的數(shù)據(jù)存儲(chǔ)格式,并且不依賴任何語言(and is a language-neutral)。
14. 使用正確的 <script> 標(biāo)簽
不贊成在 <script> 中的使用LANGUAGE 屬性。一個(gè)合適的方式是創(chuàng)建如下的 Javascript 代碼塊:
<script type="text/javascript"> // code here </script>
PS:上述代碼沒有經(jīng)過格式化處理,通常格式化處理后的代碼會(huì)比較容易閱讀理解,小編這里就為大家推薦幾款在線格式化與壓縮工具,方便大家在今后的開發(fā)中使用:
在線JavaScript代碼美化、格式化工具:
http://tools.jb51.net/code/js
JavaScript代碼美化/壓縮/格式化/加密工具:
http://tools.jb51.net/code/jscompress
jsmin在線js壓縮工具:
http://tools.jb51.net/code/jsmincompress
json代碼在線格式化/美化/壓縮/編輯/轉(zhuǎn)換工具:
http://tools.jb51.net/code/jsoncodeformat
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《JavaScript切換特效與技巧總結(jié)》、《JavaScript查找算法技巧總結(jié)》、《JavaScript動(dòng)畫特效與技巧匯總》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- js動(dòng)態(tài)調(diào)用css屬性的小規(guī)律及實(shí)例說明
- JavaScript 錯(cuò)誤處理與調(diào)試經(jīng)驗(yàn)總結(jié)
- js下關(guān)于onmouseout、事件冒泡的問題經(jīng)驗(yàn)小結(jié)
- 寫給想學(xué)習(xí)Javascript的朋友一點(diǎn)學(xué)習(xí)經(jīng)驗(yàn)小結(jié)
- javascript 操作select下拉列表框的一點(diǎn)小經(jīng)驗(yàn)
- JS前端框架關(guān)于重構(gòu)的失敗經(jīng)驗(yàn)分享
- JS效率個(gè)人經(jīng)驗(yàn)談(8-15更新),加入range技巧
- javascript 框架小結(jié) 個(gè)人工作經(jīng)驗(yàn)
- jquery.validate.js插件使用經(jīng)驗(yàn)記錄
- Javascript 多瀏覽器兼容總結(jié)(實(shí)戰(zhàn)經(jīng)驗(yàn))
- 使用node.js半年來總結(jié)的 10 條經(jīng)驗(yàn)
- javascript 構(gòu)造函數(shù)強(qiáng)制調(diào)用經(jīng)驗(yàn)總結(jié)
相關(guān)文章
javascript jscroll模擬html元素滾動(dòng)條
這里是自己在工作不太忙的時(shí)候?qū)懗鰜砹艘粋€(gè)用戶可以自定義的滾動(dòng)條jscroll,以下簡稱jscroll。jscroll默認(rèn)只提供一種滾動(dòng)條樣式,部分樣式來自google webstore ,其中有部分css3樣式主要用于實(shí)現(xiàn)圓角,陰影效果2012-12-12Javascript拖拽系列文章2之offsetLeft、offsetTop、offsetWidth、offsetHei
Javascript拖拽用到的一些關(guān)于位置定位的一些參數(shù)2008-09-09基于javascript實(shí)現(xiàn)樣式清新圖片輪播特效
這篇文章主要為大家詳細(xì)介紹了基于javascript實(shí)現(xiàn)樣式清新圖片輪播特效,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03javascript 兼容所有瀏覽器的DOM擴(kuò)展功能
技術(shù)文章寫得少,所以有時(shí)候想寫點(diǎn)什么卻下不了手,不知道該寫什么;往往到了準(zhǔn)備要寫的時(shí)候才發(fā)現(xiàn)自己想寫的東西其實(shí)很無聊,甚至覺得很幼稚,于是又關(guān)掉了編緝器2012-08-08詳解js私有作用域中創(chuàng)建特權(quán)方法
這篇文章主要為大家詳細(xì)介紹了js私有作用域中創(chuàng)建特權(quán)方法,何為特權(quán)方法,特權(quán)方法就是有權(quán)訪問私有變量和私有函數(shù)的公有方法,感興趣的小伙伴們可以參考一下2016-01-01javascript將DOM節(jié)點(diǎn)添加到文檔的方法實(shí)例分析
這篇文章主要介紹了javascript將DOM節(jié)點(diǎn)添加到文檔的方法,對(duì)比分析了javascript的兩種節(jié)點(diǎn)創(chuàng)建的方法,涉及javascript節(jié)點(diǎn)操作及運(yùn)行時(shí)間計(jì)算的相關(guān)技巧,需要的朋友可以參考下2015-08-08