最好最全面的前端開發(fā)規(guī)則_第1頁
最好最全面的前端開發(fā)規(guī)則_第2頁
最好最全面的前端開發(fā)規(guī)則_第3頁
最好最全面的前端開發(fā)規(guī)則_第4頁
最好最全面的前端開發(fā)規(guī)則_第5頁
已閱讀5頁,還剩38頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、.這是一份旨在增強(qiáng)團(tuán)隊的開發(fā)協(xié)作,提高代碼質(zhì)量和打造開發(fā)基石的編碼風(fēng)格規(guī)范,其中包含了 HTML, JavaScript 和 CSS/SCSS 這幾個部分。我們知道,當(dāng)一個團(tuán)隊開始指定并實行編碼規(guī)范的話,錯誤就會變得更加顯而易見。如果一段特定的代碼不符合規(guī)范的話,它有可能只是代碼風(fēng)格錯誤,而也有可能會是 bug。早期指定規(guī)范就使得代碼審核得以更好的開展,并且可以更精確的地定位到錯誤。只要開發(fā)者們能夠保證源代碼源文件都嚴(yán)格遵循規(guī)范,那接下去所使用的混淆、壓縮和編譯工具則可投其所好不盡相同。一般規(guī)范以下章節(jié)列舉了一些可應(yīng)用在 HTML, JavaScript 和 CSS/SCSS 上的通用規(guī)則。文

2、件/資源命名在 web 項目中,所有的文件名應(yīng)該都遵循同一命名約定。以可讀性而言,減號-是用來分隔文件名的不二之選。同時它也是常見的 URL 分隔符i.e./blog/my-blog-entryor,所以理所當(dāng)然的,減號應(yīng)該也是用來分隔資源名稱的好選擇。請確保文件命名總是以字母開頭而不是數(shù)字。而以特殊字符開頭命名的文件,一般都有特殊的含義與用處比如 compass1中的下劃線就是用來標(biāo)記跳過直接編譯的文件用的。資源的字母名稱必須全為小寫,這是因為在某些對大小寫字母敏感的操作系統(tǒng)中,當(dāng)文件通過工具壓縮混淆后,或者人為修改過后,大小寫不同而導(dǎo)致引用文件不同的錯誤,很難被發(fā)現(xiàn)。還有一些情況下,需要對

3、文件增加前后綴或特定的擴(kuò)展名比如 .min.js, .min.css,抑或一串前綴比如。這種情況下,建議使用點分隔符來區(qū)分這些在文件名中帶有清晰意義的元數(shù)據(jù)。不推薦MyScript.jsmyCamelCaseName.cssi_love_underscores.html1001-scripts.jsmy-file-min.css推薦my-script.jsmy-camel-case-name.cssi-love-underscores.htmlthousand-and-one-scripts.js協(xié)議不要指定引入資源所帶的具體協(xié)議。當(dāng)引入圖片或其他媒體文件,還有樣式和腳本時,URLs 所指向的

4、具體路徑,不要指定協(xié)議部分http:,https:,除非這兩者協(xié)議都不可用。不指定協(xié)議使得 URL 從絕對的獲取路徑轉(zhuǎn)變?yōu)橄鄬Φ?在請求資源協(xié)議無法確定時非常好用,而且還能為文件大小節(jié)省幾個字節(jié)。不推薦推薦不推薦.example background: url;推薦.example background: url;文本縮進(jìn)一次縮進(jìn)兩個空格。FantasticGreatTestmedia screen and body font-size:100%;functionvar x =10;function yreturn result:* x;注釋注釋是你自己與你的小伙伴們了解代碼寫法和目的的唯一途

5、徑。特別是在寫一些看似瑣碎的無關(guān)緊要的代碼時,由于記憶點不深刻,注釋就變得尤為重要了。編寫自解釋代碼只是一個傳說,沒有任何代碼是可以完全自解釋的。而代碼注釋,則是永遠(yuǎn)也不嫌多。當(dāng)你寫注釋時一定要注意:不要寫你的代碼都干了些什么,而要寫你的代碼為什么要這么寫,背后的考量是什么。當(dāng)然也可以加入所思考問題或是解決方案的鏈接地址。不推薦var offset =0;if/ Add offset of 20 offset =20;推薦var offset =0;if/ If the labels are included we need to have a minimum offset of 20 pix

6、els/ We need to set it explicitly because of the following bug: /issue-tracker/ISSUE-1 offset =20;一些注釋工具可以幫助你寫出更好的注釋。JSDoc或YUIDoc就是用來寫 JavaScript 注釋用的。你甚至可以使用工具來為這些注釋生成文檔,這也是激勵開發(fā)者們寫注釋的一個好方法,因為一旦有了這樣方便的生成文檔的工具,他們通常會開始花更多時間在注釋細(xì)節(jié)上。代碼檢查對于比較寬松自由的編程語言來說,嚴(yán)格遵循編碼規(guī)范和格式化風(fēng)格指南就顯得極為重要。遵循規(guī)范固然很好,但是有自動化流程來確保其執(zhí)行情況,豈不

7、更佳。Trust is good, control is better.對于 JavaScript,建議使用JSLint或JSHint。HTML 規(guī)范文檔類型推薦使用 HTML5 的文檔類型申明:.建議使用 text/html 格式的 HTML。避免使用 XHTML。XHTML 以及它的屬性,比如application/xhtml+xml在瀏覽器中的應(yīng)用支持與優(yōu)化空間都十分有限。HTML 中最好不要將無內(nèi)容元素1的標(biāo)簽閉合,例如:使用而非.HTML 驗證一般情況下,建議使用能通過標(biāo)準(zhǔn)規(guī)范驗證的 HTML 代碼,除非在性能優(yōu)化和控制文件大小上不得不做出讓步。使用諸如 W3C HTML valid

8、ator 這樣的工具來進(jìn)行檢測。規(guī)范化的 HTML 是顯現(xiàn)技術(shù)要求與局限的顯著質(zhì)量基線,它促進(jìn)了 HTML 被更好地運用。不推薦TestThis is only a test.推薦TestThis is only a test.省略可選標(biāo)簽HTML5 規(guī)范中規(guī)定了 HTML 標(biāo)簽是可以省略的。但從可讀性來說,在開發(fā)的源文件中最好不要這樣做,因為省略標(biāo)簽可能會導(dǎo)致一些問題。省略一些可選的標(biāo)簽確實使得頁面大小減少,這很有用,尤其是對于一些大型網(wǎng)站來說。為了達(dá)到這一目的,我們可以在開發(fā)后期對頁面進(jìn)行壓縮處理,在這個環(huán)節(jié)中這些可選的標(biāo)簽完全就可以省略掉了。腳本加載出于性能考慮,腳本異步加載很關(guān)鍵。一段

9、腳本放置在內(nèi),比如,其加載會一直阻塞 DOM 解析,直至它完全地加載和執(zhí)行完畢。這會造成頁面顯示的延遲。特別是一些重量級的腳本,對用戶體驗來說那真是一個巨大的影響。異步加載腳本可緩解這種性能影響。如果只需兼容 IE10+,可將 HTML5 的 async 屬性加至腳本中,它可防止阻塞 DOM 的解析,甚至你可以將腳本引用寫在里也沒有影響。如需兼容老舊的瀏覽器,實踐表明可使用用來動態(tài)注入腳本的腳本加載器。你可以考慮yepnope或labjs。注入腳本的一個問題是:一直要等到 CSS 對象文檔已就緒,它們才開始加載短暫地在 CSS 加載完畢之后,這就對需要及時觸發(fā)的 JS 造成了一定的延遲,這多多

10、少少也影響了用戶體驗吧。終上所述,兼容老舊瀏覽器時,應(yīng)該遵循以下最佳實踐。腳本引用寫在 body 結(jié)束標(biāo)簽之前,并帶上 async 屬性。這雖然在老舊瀏覽器中不會異步加載腳本,但它只阻塞了 body 結(jié)束標(biāo)簽之前的 DOM 解析,這就大大降低了其阻塞影響。而在現(xiàn)代瀏覽器中,腳本將在 DOM 解析器發(fā)現(xiàn) body 尾部的 script 標(biāo)簽才進(jìn)行加載,此時加載屬于異步加載,不會阻塞 CSSOM但其執(zhí)行仍發(fā)生在 CSSOM 之后。所有瀏覽器中,推薦只在現(xiàn)代瀏覽器中,推薦語義化根據(jù)元素有時被錯誤地稱作標(biāo)簽其被創(chuàng)造出來時的初始意義來使用它。打個比方,用 heading 元素來定義頭部標(biāo)題,p 元素來定

11、義文字段落,用 a 元素來定義鏈接錨點,等等。有根據(jù)有目的地使用 HTML 元素,對于可訪問性、代碼重用、代碼效率來說意義重大。以下示例列出了一些的語義化 HTML 主要情況:不推薦My page titleHomeNewsAboutAll news articlesBad articleIntroduction sub-titleThis is a very bad example for HTML semanticsI think Im more on the side and should not receive the main credits This article was cre

12、ated by David 2014-01-01 00:00 Related sections: Events, Public holidays Copyright 2014推薦My page title!- A listing of elements should always go to UL -HomeNewsAbout!- The main part of the page should go into a main element -!- As a page section belongs to the page structure heading elements should b

13、e used -All news articles!- If a section / module can be seen as an article a article element should be used -Good articleIntroduction sub-titleThis is a good example for HTML semanticsI think Im more on the side and should not receive the main creditsThis article was created by David 1 month agoRel

14、ated sections: Events, Public holidays Copyright 2014多媒體回溯對頁面上的媒體而言,像圖片、視頻、canvas 動畫等,要確保其有可替代的接入接口。圖片文件我們可采用有意義的備選文本alt,視頻和音頻文件我們可以為其加上說明文字或字幕。提供可替代內(nèi)容對可用性來說十分重要。試想,一位盲人用戶如何能知曉一張圖片是什么,要是沒有 alt 的話。圖片的 alt 屬性是可不填寫內(nèi)容的,純裝飾性的圖片就可用這么做:alt=。不推薦推薦盡量用 alt 標(biāo)簽去描述圖片,設(shè)想你需要對于那些只能通過語音或者看不見圖片的用戶表達(dá)圖片到底是什么。不推薦推薦關(guān)注點分離

15、理解 web 中如何和為何區(qū)分不同的關(guān)注點,這很重要。這里的關(guān)注點主要指的是:信息HTML 結(jié)構(gòu)、外觀CSS和行為JavaScript。為了使它們成為可維護(hù)的干凈整潔的代碼,我們要盡可能的將它們分離開來。嚴(yán)格地保證結(jié)構(gòu)、表現(xiàn)、行為三者分離,并盡量使三者之間沒有太多的交互和聯(lián)系。就是說,盡量在文檔和模板中只包含結(jié)構(gòu)性的 HTML;而將所有表現(xiàn)代碼,移入樣式表中;將所有動作行為,移入腳本之中。在此之外,為使得它們之間的聯(lián)系盡可能的小,在文檔和模板中也盡量少地引入樣式和腳本文件。清晰的分層意味著:不使用超過一到兩張樣式表i.e. main.css, vendor.css不使用超過一到兩個腳本學(xué)會用合

16、并腳本不使用行內(nèi)樣式.no-good 不在元素上使用 style 屬性不使用行內(nèi)腳本alert不使用表象元素i.e.,不使用表象 class 名i.e. red, left, center不推薦Im a subtitle and Im bold!Dare you center me! alert;Im important!推薦Im a subtitle and Im bold!Dare you center me!Im important!HTML 內(nèi)容至上不要讓非內(nèi)容信息污染了你的 HTML?,F(xiàn)在貌似有一種傾向:通過 HTML 來解決設(shè)計問題,這是顯然是不對的。HTML 就應(yīng)該只關(guān)注內(nèi)容。H

17、TML 標(biāo)簽的目的,就是為了不斷地展示內(nèi)容信息。不要引入一些特定的 HTML 結(jié)構(gòu)來解決一些視覺設(shè)計問題不要將img元素當(dāng)做專門用來做視覺設(shè)計的元素以下例子展示了誤將 HTML 用來解決設(shè)計問題的這兩種情況:不推薦 See the square next to me?.text-box .square display:inline-block; width:1rem; height:1rem; background-color: red;推薦 See the square next to me?/* We use a :before pseudo element to solve the de

18、sign problem of placing a colored square in front of the text content */.text-box:before content:; display:inline-block; width:1rem; height:1rem; background-color: red;圖片和 SVG 圖形能被引入到 HTML 中的唯一理由是它們呈現(xiàn)出了與內(nèi)容相關(guān)的一些信息。不推薦 See the square next to me?推薦 See the square next to me?/* We use a :before pseudo e

19、lement with a background image to solve the problem */.text-box:before content:; display:inline-block; width:1rem; height:1rem; background: urlno-repeat; background-size:100%;Type 屬性省略樣式表與腳本上的 type 屬性。鑒于 HTML5 中以上兩者默認(rèn)的 type 值就是 text/css 和 text/javascript,所以 type 屬性一般是可以忽略掉的。甚至在老舊版本的瀏覽器中這么做也是安全可靠的。不推

20、薦推薦可用性如果 HTML5 語義化標(biāo)簽使用得當(dāng),許多可用性問題已經(jīng)引刃而解。ARIA 規(guī)則在一些語義化的元素上可為其添上默認(rèn)的可用性角色屬性,使用得當(dāng)?shù)脑捯咽咕W(wǎng)站的可用性大部分成立。假如你使用nav,aside,main,footer等元素,ARIA 規(guī)則會在其上應(yīng)用一些關(guān)聯(lián)的默認(rèn)值。更多細(xì)節(jié)可參考 HYPERLINK /w3c/aria-in-html/master/index.html l recommendations-table ARIA specification另外一些角色屬性則能夠用來呈現(xiàn)更多可用性情景i.e.role=tab。Tab Index 在可用性上的運用檢查文檔中的

21、tab 切換順序并傳值給元素上的 tabindex,這可以依據(jù)元素的重要性來重新排列其 tab 切換順序。你可以設(shè)置tabindex=-1在任何元素上來禁用其 tab 切換。當(dāng)你在一個默認(rèn)不可聚焦的元素上增加了功能,你應(yīng)該總是為其加上tabindex屬性使其變?yōu)榭删劢範(fàn)顟B(tài),而且這也會激活其 CSS 的偽類:focus。選擇合適的tabindex值,或是直接使用tabindex=0將元素們組織成同一 tab 順序水平,并強(qiáng)制干預(yù)其自然閱讀順序。微格式在 SEO 和可用性上的運用如果 SEO 和可用性環(huán)境條件允許的話,建議考慮采用微格式。微格式是通過在元素標(biāo)簽上申明一系列特定數(shù)據(jù)來達(dá)成特定語義的方

22、法。谷歌、微軟和雅虎對如何使用這些額外的數(shù)據(jù)一定程度上的達(dá)成一致,如果正確的使用,這將給搜索引擎優(yōu)化帶來巨大的好處。你可以訪問獲得更多內(nèi)容細(xì)節(jié)??匆粋€電影網(wǎng)站的簡單例子:不帶微格式AvatarDirector: James Cameron Science fictionTrailer帶有微格式Avatar Director: James Cameron born August 16, 1954Science fictionTrailerID 和錨點通常一個比較好的做法是將頁面內(nèi)所有的頭部標(biāo)題元素都加上 ID. 這樣做,頁面 URL 的 hash 中帶上對應(yīng)的 ID 名稱,即形成描點,方便跳轉(zhuǎn)至

23、對應(yīng)元素所處位置。打個比方,當(dāng)你在瀏覽器中輸入 URL/about#best-practices,瀏覽器將定位至以下 H3 上。Best practices格式化規(guī)則在每一個塊狀元素,列表元素和表格元素后,加上一新空白行,并對其子孫元素進(jìn)行縮進(jìn)。內(nèi)聯(lián)元素寫在一行內(nèi),塊狀元素還有列表和表格要另起一行。如果由于換行的空格引發(fā)了不可預(yù)計的問題,那將所有元素并入一行也是可以接受的,格式警告總好過錯誤警告。推薦Space, the final frontier.MoeLarryCurlyIncomeTaxes$ 5.00$ 4.50HTML 引號使用雙引號 而不是單引號 。不推薦推薦1: 此處的空白元素

24、指的是以下元素:area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbrJavaScript 規(guī)范全局命名空間污染與 IIFE總是將代碼包裹成一個 IIFE,用以創(chuàng)建獨立隔絕的定義域。這一舉措可防止全局命名空間被污染。IIFE 還可確保你的代碼不會輕易被其它全局命名空間里的代碼所修改i.e. 第三方庫,window 引用,被覆蓋的未定義的關(guān)鍵字等等。不推薦var x =10, y =100;/ Declaring variables in the global scope is res

25、ulting in global scope pollution. All variables declared like this/ will be stored in the window object. This is very unclean and needs to be avoided.console.log;推薦/ We declare a IIFE and pass parameters into the function that we will use from the global spacefunctionuse strict;var x =10, y =100;/ W

26、ill output true true log+ +;IIFE立即執(zhí)行的函數(shù)表達(dá)式無論何時,想要創(chuàng)建一個新的封閉的定義域,那就用 IIFE。它不僅避免了干擾,也使得內(nèi)存在執(zhí)行完后立即釋放。所有腳本文件建議都從 IIFE 開始。立即執(zhí)行的函數(shù)表達(dá)式的執(zhí)行括號應(yīng)該寫在外包括號內(nèi)。雖然寫在內(nèi)還是寫在外都是有效的,但寫在內(nèi)使得整個表達(dá)式看起來更像一個整體,因此推薦這么做。不推薦function;推薦function;so,用下列寫法來格式化你的 IIFE 代碼:functionuse strict;/ Code goes here;如果你想引用全局變量或者是外層 IIFE 的變量,可以通過下列方式傳

27、參:functionuse strict; $function w.alertd.querySelectorAll.length;嚴(yán)格模式ECMAScript 5 嚴(yán)格模式可在整個腳本或獨個方法內(nèi)被激活。它對應(yīng)不同的 javascript 語境會做更加嚴(yán)格的錯誤檢查。嚴(yán)格模式也確保了 javascript 代碼更加的健壯,運行的也更加快速。嚴(yán)格模式會阻止使用在未來很可能被引入的預(yù)留關(guān)鍵字。你應(yīng)該在你的腳本中啟用嚴(yán)格模式,最好是在獨立的 IIFE 中應(yīng)用它。避免在你的腳本第一行使用它而導(dǎo)致你的所有腳本都啟動了嚴(yán)格模式,這有可能會引發(fā)一些第三方類庫的問題。不推薦/ Script starts he

28、reuse strict;function/ Your code starts here;推薦functionuse strict;/ Your code starts here;變量聲明總是使用var來聲明變量。如不指定 var,變量將被隱式地聲明為全局變量,這將對變量難以控制。如果沒有聲明,變量處于什么定義域就變得不清可以是在 Document 或 Window 中,也可以很容易地進(jìn)入本地定義域。所以,請總是使用 var 來聲明變量。采用嚴(yán)格模式帶來的好處是,當(dāng)你手誤輸入錯誤的變量名時,它可以通過報錯信息來幫助你定位錯誤出處。不推薦x =10;y =100;推薦var x =10, y =

29、100;理解 JavaScript 的定義域和定義域提升在 JavaScript 中變量和方法定義會自動提升到執(zhí)行之前。JavaScript 只有 function 級的定義域,而無其他很多編程語言中的塊定義域,所以使得你在某一 function 內(nèi)的某語句和循環(huán)體中定義了一個變量,此變量可作用于整個 function 內(nèi),而不僅僅是在此語句或循環(huán)體中,因為它們的聲明被 JavaScript 自動提升了。我們通過例子來看清楚這到底是怎么一回事:原 functionfunctionuse strict;var a =10;forvar i =0; i var b = i * i; log;ifv

30、ar f =function log; f;function x log; x;被 JS 提升過后functionuse strict;/ All variables used in the closure will be hoisted to the top of the functionvar a, i, b, f;/ All functions in the closure will be hoisted to the topfunction x log; a =10;fori =0; i b = i * i; log;if/ Function assignments will only

31、 result in hoisted variables but the function body will not be hoisted/ Only by using a real function declaration the whole function will be hoisted with its body f =function log; f; x;根據(jù)以上提升過程,你是否可理解以下代碼?有效代碼functionuse strict;var a =10; i =5; x;forvar i; i log;var b = i * i;if f =function log; f;v

32、ar f;function x log;正如你所看到的這段令人充滿困惑與誤解的代碼導(dǎo)致了出人意料的結(jié)果。只有良好的聲明習(xí)慣,也就是下一章節(jié)我們要提到的聲明規(guī)則,才能盡可能的避免這類錯誤風(fēng)險。提升聲明為避免上一章節(jié)所述的變量和方法定義被自動提升造成誤解,把風(fēng)險降到最低,我們應(yīng)該手動地顯示地去聲明變量與方法。也就是說,所有的變量以及方法,應(yīng)當(dāng)定義在 function 內(nèi)的首行。只用一個var關(guān)鍵字聲明,多個變量用逗號隔開。不推薦functionuse strict;var a =10;var b =10;forvar i =0; i var c = a * b * i;function fvar

33、d =100;var x =functionreturn d * d; logx;推薦functionuse strict;var a =10, b =10, i, c, d, x;function ffori =0; i c = a * b * i; d =100; x =functionreturn d * d; logx;把賦值盡量寫在變量申明中。不推薦var a, b, c;a =10;b =10;c =100;推薦var a =10, b =10, c =100;總是使用帶類型判斷的比較判斷總是使用=精確的比較操作符,避免在判斷的過程中,由 JavaScript 的強(qiáng)制類型轉(zhuǎn)換所造成

34、的困擾。如果你使用=操作符,那比較的雙方必須是同一類型為前提的條件下才會有效。如果你想了解更多關(guān)于強(qiáng)制類型轉(zhuǎn)換的信息,你可以讀一讀Dmitry Soshnikov 的這篇文章。在只使用=的情況下,JavaScript 所帶來的強(qiáng)制類型轉(zhuǎn)換使得判斷結(jié)果跟蹤變得復(fù)雜,下面的例子可以看出這樣的結(jié)果有多怪了:functionuse strict; log;/ true log;/ true log;/ true log;/ truevar x = valueOf:functionreturnX; log;明智地使用真假判斷當(dāng)我們在一個 if 條件語句中使用變量或表達(dá)式時,會做真假判斷。if是不同于if

35、的。后者的判斷比較特殊,我們稱其為真假判斷。這種判斷會通過特殊的操作將其轉(zhuǎn)換為 true 或 false,下列表達(dá)式統(tǒng)統(tǒng)返回 false:false,0,undefined,null,NaN,空字符串.這種真假判斷在我們只求結(jié)果而不關(guān)心過程的情況下,非常的有幫助。以下示例展示了真假判斷是如何工作的:functionuse strict;function logTruthyFalsyif log;else log; logTruthyFalsy;/ truthy logTruthyFalsy;/ truthy logTruthyFalsy;/ truthy logTruthyFalsy;/ tr

36、uthy logTruthyFalsy;/ truthy logTruthyFalsy;/ falsy logTruthyFalsy;/ falsy logTruthyFalsy;/ falsy logTruthyFalsy;/ falsy logTruthyFalsy;/ falsy logTruthyFalsy;/ falsy;變量賦值時的邏輯操作邏輯操作符|和&也可被用來返回布爾值。如果操作對象為非布爾對象,那每個表達(dá)式將會被自左向右地做真假判斷?;诖瞬僮?最終總有一個表達(dá)式被返回回來。這在變量賦值時,是可以用來簡化你的代碼的。不推薦ifif x =1;else x = y;推薦x =

37、 x | y |1;這一小技巧經(jīng)常用來給方法設(shè)定默認(rèn)的參數(shù)。functionuse strict;function multiply a = a |1; b = b |1; log; multiply;/ Result 1 multiply;/ Result 10 multiply;/ Result 3 multiply;/ Result 45;分號總是使用分號,因為隱式的代碼嵌套會引發(fā)難以察覺的問題。當(dāng)然我們更要從根本上來杜絕這些問題1。以下幾個示例展示了缺少分號的危害:/ 1.MyCtotype.myMethod =functionreturn42;/ No semicolon here.

38、function/ Some initialization code wrapped in a function to create a scope for locals.;var x =i:1,j:2/ No semicolon here./ 2. Trying to do one thing on Internet Explorer and another on Firefox./ I know youd never write code like this, but throw me a bone.ffVersion, ieVersionisIE;var THINGS_TO_EAT =a

39、pples, oysters, sprayOnCheese/ No semicolon here./ 3. conditional execution a la bash-1= resultOfOperation| die;So what happens?JavaScript 錯誤 首先返回 42 的那個 function 被第二個 function 當(dāng)中參數(shù)傳入調(diào)用,接著數(shù)字 42 也被調(diào)用而導(dǎo)致出錯。八成你會得到 no such property in undefined 的錯誤提示,因為在真實環(huán)境中的調(diào)用是這個樣子:xffVersion, ieVersionisIE.die總是被調(diào)用。因

40、為數(shù)組減 1 的結(jié)果是NaN,它不等于任何東西無論resultOfOperation是否返回NaN。所以最終的結(jié)果是die執(zhí)行完所獲得值將賦給THINGS_TO_EAT.Why?JavaScript 中語句要以分號結(jié)束,否則它將會繼續(xù)執(zhí)行下去,不管換不換行。以上的每一個示例中,函數(shù)聲明或?qū)ο蠡驍?shù)組,都變成了在一句語句體內(nèi)。要知道閉合圓括號并不代表語句結(jié)束,JavaScript 不會終結(jié)語句,除非它的下一個 token 是一個中綴符2或者是圓括號操作符。這真是讓人大吃一驚,所以乖乖地給語句末加上分號吧。澄清:分號與函數(shù)分號需要用在表達(dá)式的結(jié)尾,而并非函數(shù)聲明的結(jié)尾。區(qū)分它們最好的例子是:var

41、foo =functionreturntrue;/ semicolon here.function fooreturntrue;/ no semicolon here.嵌套函數(shù)嵌套函數(shù)是非常有用的,比如用在持續(xù)創(chuàng)建和隱藏輔助函數(shù)的任務(wù)中。你可以非常自由隨意地使用它們。語句塊內(nèi)的函數(shù)聲明切勿在語句塊內(nèi)聲明函數(shù),在 ECMAScript 5 的嚴(yán)格模式下,這是不合法的。函數(shù)聲明應(yīng)該在定義域的頂層。但在語句塊內(nèi)可將函數(shù)申明轉(zhuǎn)化為函數(shù)表達(dá)式賦值給變量。不推薦iffunction foo推薦ifvar foo =function;異?;旧夏銦o法避免出現(xiàn)異常,特別是在做大型開發(fā)時使用應(yīng)用開發(fā)框架等等。在

42、沒有自定義異常的情況下,從有返回值的函數(shù)中返回錯誤信息一定非常的棘手,更別提多不優(yōu)雅了。不好的解決方案包括了傳第一個引用類型來接納錯誤信息,或總是返回一個對象列表,其中包含著可能的錯誤對象。以上方式基本上是比較簡陋的異常處理方式。適時可做自定義異常處理。在復(fù)雜的環(huán)境中,你可以考慮拋出對象而不僅僅是字符串默認(rèn)的拋出值。ifthrow name:System Error, message:A name should always be specified!標(biāo)準(zhǔn)特性總是優(yōu)先考慮使用標(biāo)準(zhǔn)特性。為了最大限度地保證擴(kuò)展性與兼容性,總是首選標(biāo)準(zhǔn)的特性,而不是非標(biāo)準(zhǔn)的特性例如:首選string.charAt而

43、不是string3;首選 DOM 的操作方法來獲得元素引用,而不是某一應(yīng)用特定的快捷方法。簡易的原型繼承如果你想在 JavaScript 中繼承你的對象,請遵循一個簡易的模式來創(chuàng)建此繼承。如果你預(yù)計你會遇上復(fù)雜對象的繼承,那可以考慮采用一個繼承庫,比如Proto.js by Axel Rauschmayer.簡易繼承請用以下方式:functionuse strict;/ Constructor functionfunctionApple = name;/ Defining a method of appleAtotype.eat =function log;/ Constructor func

44、tionfunctionGrannySmithApple/ Invoking parent constructorAtotype.constructor.call;/ Set parent prototype while creating a copy with Object.createGrannySmithAtotype =Object.create;/ Set constructor to the sub type, otherwise points to AppleGrannySmithAtotype.constructor =GrannySmithApple;/ Calling a

45、super methodGrannySmithAtotype.eat =function/ Be sure to apply it onto our current object with callAtotype.eat.call; log;/ Instantiationvar apple =newApple;var grannyApple =newGrannySmithApple; log;/ Test Apple log;/ Granny Smith/ Instance checks log;/ true log;/ false log;/ true log;/ true/ Calling

46、 method that calls super method grannyApple.eat;/ Eating Granny SmithnPoor Grany Smith;使用閉包閉包的創(chuàng)建也許是 JS 最有用也是最易被忽略的能力了。關(guān)于閉包如何工作的合理解釋。切勿在循環(huán)中創(chuàng)建函數(shù)在簡單的循環(huán)語句中加入函數(shù)是非常容易形成閉包而帶來隱患的。下面的例子就是一個典型的陷阱:不推薦functionuse strict;/ numbers and i is defined in the current function closurevar numbers =1,2,3, i;fori =0; i w

47、.setTimeoutfunction/ At the moment when this gets executed the i variable, coming from the outer function scope/ is set to 3 and the current program is alerting the message 3 times/ Index 3 with number undefined/ If you understand closures in javascript you know how to deal with those cases/ Its bes

48、t to just avoid functions / new closures in loops as this prevents those issues w.alert;,0;接下來的改進(jìn)雖然已經(jīng)解決了上述例子中的問題或 bug,但還是違反了不在循環(huán)中創(chuàng)建函數(shù)或閉包的原則。不推薦functionuse strict;/ numbers and i is defined in the current function closurevar numbers =1,2,3, i;fori =0; i / Creating a new closure scope with an IIFE sol

49、ves the problem/ The delayed function will use index and number which are/ in their own closure scope ./ / Still this is not recommended as we violate our rule to not/ create functions within loops and we are creating two!function w.setTimeoutfunction/ Will output as expected 0 1, 1 2, 2 3 w.alert;,

50、0;接下來的改進(jìn)已解決問題,而且也遵循了規(guī)范??墒?你會發(fā)現(xiàn)看上去似乎過于復(fù)雜繁冗了,應(yīng)該會有更好的解決方案吧。不完全推薦functionuse strict;/ numbers and i is defined in the current function closurevar numbers =1,2,3, i;/ Create a function outside of the loop that will accept arguments to create a/ function closure scope. This function will return a function

51、 that executes in this/ closure parent scope.function alertIndexWithNumberreturnfunction w.alert;/ First parameter is a function call that returns a function./ / This solves our problem and we dont create a function inside our loopfori =0; i w.setTimeoutalertIndexWithNumber,0;將循環(huán)語句轉(zhuǎn)換為函數(shù)執(zhí)行的方式問題能得到立馬解

52、決,每一次循環(huán)都會對應(yīng)地創(chuàng)建一次閉包。函數(shù)式的風(fēng)格更加值得推薦,而且看上去也更加地自然和可預(yù)料。推薦functionuse strict;/ numbers and i is defined in the current function closurevar numbers =1,2,3, i; numbers.forEachfunction w.setTimeoutfunction w.alert;,0;eval 函數(shù)魔鬼eval不但混淆語境還很危險,總會有比這更好、更清晰、更安全的另一種方案來寫你的代碼,因此盡量不要使用 evil 函數(shù)。this 關(guān)鍵字只在對象構(gòu)造器、方法和在設(shè)定的閉包

53、中使用this關(guān)鍵字。this 的語義在此有些誤導(dǎo)。它時而指向全局對象大多數(shù)時,時而指向調(diào)用者的定義域在 eval 中,時而指向 DOM 樹中的某一節(jié)點當(dāng)用事件處理綁定到 HTML 屬性上時,時而指向一個新創(chuàng)建的對象在構(gòu)造器中,還時而指向其它的一些對象如果函數(shù)被call和apply執(zhí)行和調(diào)用時。正因為它是如此容易地被搞錯,請限制它的使用場景:在構(gòu)造函數(shù)中在對象的方法中包括由此創(chuàng)建出的閉包內(nèi)首選函數(shù)式風(fēng)格函數(shù)式編程讓你可以簡化代碼并縮減維護(hù)成本,因為它容易復(fù)用,又適當(dāng)?shù)亟怦詈透俚囊蕾?。接下來的例子?在一組數(shù)字求和的同一問題上,比較了兩種解決方案。第一個例子是經(jīng)典的程序處理,而第二個例子則是采

54、用了函數(shù)式編程和 ECMA Script 5.1 的數(shù)組方法。例外:往往在重代碼性能輕代碼維護(hù)的情況之下,要選擇最優(yōu)性能的解決方案而非維護(hù)性高的方案比如用簡單的循環(huán)語句代替 forEach。不推薦functionuse strict;var arr =10,3,7,9,100,20, sum =0, i;fori =0; i sum += arri; log;推薦functionuse strict;var arr =10,3,7,9,100,20;var sum = arr.reducefunctionreturn prevValue + currentValue;,0; log;另一個例子

55、通過某一規(guī)則對一個數(shù)組進(jìn)行過濾匹配來創(chuàng)建一個新的數(shù)組。不推薦functionuse strict;var numbers =11,3,7,9,100,20,14,10, numbersGreaterTen =, i;fori =0; i if10 numbersGreaterTen.push; log;推薦functionuse strict;var numbers =11,3,7,9,100,20,14,10;var numbersGreaterTen = numbers.filterfunctionreturn element 10; log;使用 ECMA Script 5建議使用 EC

56、MA Script 5 中新增的語法糖和函數(shù)。這將簡化你的程序,并讓你的代碼更加靈活和可復(fù)用。數(shù)組和對象的屬性迭代用 ECMA5 的迭代方法來迭代數(shù)組。使用Array.forEach或者如果你要在特殊場合下中斷迭代,那就用Array.every。functionuse strict;/ Iterate over an array and break at a certain condition1,2,3,4,5.everyfunction log;ifreturntrue;/ Defining a simple javascript objectvar obj = a:A, b:B,c-d-e

57、:CDE;/ Iterating over the object keysObject.keys.forEachfunction log;不要使用 switchswitch 在所有的編程語言中都是個非常錯誤的難以控制的語句,建議用 if else 來替換它。數(shù)組和對象字面量用數(shù)組和對象字面量來代替數(shù)組和對象構(gòu)造器。數(shù)組構(gòu)造器很容易讓人在它的參數(shù)上犯錯。不推薦/ Length is 3.var a1 =newArray;/ Length is 2.var a2 =newArray;/ If x1 is a number and it is a natural number the length

58、will be x1./ If x1 is a number but not a natural number this will throw an exception./ Otherwise the array will have one element with x1 as its value.var a3 =newArray;/ Length is 0.var a4 =newArray;正因如此,如果將代碼傳參從兩個變?yōu)橐粋€,那數(shù)組很有可能發(fā)生意料不到的長度變化。為避免此類怪異狀況,請總是采用更多可讀的數(shù)組字面量。推薦var a =x1, x2, x3;var a2 =x1, x2;va

59、r a3 =x1;var a4 =;對象構(gòu)造器不會有類似的問題,但是為了可讀性和統(tǒng)一性,我們應(yīng)該使用對象字面量。不推薦var o =newObject;var o2 =newObject;o2.a =0;o2.b =1;o2.c =2;o2strange key=3;應(yīng)該寫成這樣:推薦var o =;var o2 = a:0, b:1, c:2,strange key:3;修改內(nèi)建對象的原型鏈修改內(nèi)建的諸如Ototype和Atotype是被嚴(yán)厲禁止的。修改其它的內(nèi)建對象比如Ftotype,雖危害沒那么大,但始終還是會導(dǎo)致在開發(fā)過程中難以 debug 的問題,應(yīng)當(dāng)也要避免。自定義 toStrin

60、g 方法你可以通過自定義toString來控制對象字符串化。這很好,但你必須保證你的方法總是成功并不會有其它副作用。如果你的方法達(dá)不到這樣的標(biāo)準(zhǔn),那將會引發(fā)嚴(yán)重的問題。如果toString調(diào)用了一個方法,這個方法做了一個斷言3,當(dāng)斷言失敗,它可能會輸出它所在對象的名稱,當(dāng)然對象也需要調(diào)用toString。圓括號一般在語法和語義上真正需要時才謹(jǐn)慎地使用圓括號。不要用在一元操作符上,例如delete,typeof和void,或在關(guān)鍵字之后,例如return,throw,case,new等。字符串統(tǒng)一使用單引號,不使用雙引號。這在創(chuàng)建 HTML 字符串非常有好處:var msg =This is s

溫馨提示

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

最新文檔

評論

0/150

提交評論