用JSLint精煉提升JavaScript代碼

由于移動應用的盛行和HTML5的廣泛運用,JavaScript正越來越流行。JavaScript受歡迎的部分原因是因為它的靈活便捷,你可以快速上手,它不需要重量級的開發環境,也不需要第三方應用支持,只要你打開一個文本編輯器,然后保存,最后通過網頁瀏覽器運行即可。

  但是,對于新手而言,使用JavaScript處處存在陷阱。在一段復雜的腳本中,JavaScript語言的延展性常常引起怪異的bug。例如,未聲明的局部變量可能會不知不覺修改全局變量。

  現在,打開JSLint網站,正如其網站所言,它是“JavaScript代碼質量工具”。JSLint的作者是Douglas Crockford,因其對JavaScript(ECMAScript)和JSON的貢獻而著名。

  (譯注:Douglas Crockford是 web領域技術權威之一,他是JSON、JSLint、JSMin和ADSafe的創造者,也是名著《JavaScript: The Good Parts》(中文版《JavaScript語言精粹?》)的作者。撰寫了許多廣為流傳、影響深遠的技術文章,包括“JavaScript:世界上最被誤解的語言”。)

  JSLint幫助JavaScript程序員在編程過程中遵循一定的編碼規范。JSLint是以基于嚴格模式(Strict Mode)為前提,參考第5版ECMAScript標準。與一般模式相比,嚴格模式下你的代碼需要按照更嚴格的規則運行。

  (譯注:對嚴格模式不了解的童鞋,可以參考這兩篇文章《ECMAScript 5.1簡介》《是時候使用JavaScript嚴謹模式(Strict Mode)提升團隊開發效率》)

  使用JSLint

  我們來用JSLint運行一個示例。寫一個簡單的jQuery插件,通過prefix顯示msg接收的信息,如果傳給type的值為false則不顯示prefix。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(function ($) {
????$.fn.loading = function(msg, type, cssClass){
????????var prefixes = {
????????????warning: 'Warning: ' + msg,
????????????error: 'Error: ' + msg,
????????????info: 'Info: ' + msg,
????????????warning: 'Caution: ' + msg,
????????};
????????if (type) {
????????????concatMsg = prefixes[type];
????????} else {
????????????concatMsg = msg;
????????}
????????$(this).each(function()? {
????????????var tis = $(this)
????????????if (msg == false) {
????????????????tis.html('');
????????????} else {
????????????????tis.html(concatMsg);
????????????}
????????});
?????}
})(jQuery);

  盡管這段代碼作為jQuery的插件運行還算正常,但當你用Firefox或Chrome運行時,會發現有幾處明顯的錯誤,以及一些不易察覺的問題。與其耗費腦力解決這些問題,不如通過JSLint來幫助我們。將上面這段代碼拷貝至JSLint網站的文本框內,然后點擊”JSLint”按鈕,代碼建議和錯誤提示會出現在下方。

  JSLint指出的第一個錯誤是:丟失“use strict”聲明。這個錯誤表示該函數未在嚴格模式下執行。為糾正該錯誤,我們在函數主體的頭部,添加“use strict”語句以啟動嚴格模式。

1
'use strict';

  加入嚴格模式聲明語句后,再次點擊“JSLint”按鈕,提示丟失“use strict”的錯誤信息將消失。現在,我們可以繼續看下一個錯誤。接下來的這個錯誤是關于空格的問題,鑒于它不能算個真正的錯誤,我們可以放心地忽略它。

  你可以將頁面最下方的“messy white space”選項改為true,這樣你就可以保留function關鍵字后不留空格的寫法。但是現在,我們保留“messy white space”選項的default屬性,因為這個功能也會幫助我們檢查其他空格問題,這個我們之后再說。

  同樣需要注意的是,雖然JSLint指出的第二個和第三個錯誤指向同一行代碼,但錯誤點并不一樣。后者JSLint建議在右括號“)”和左大括號“{”之間空一格,現在我們糾正下這個錯誤。

  插入空格后,再次點擊“JSLint”按鈕,下一個錯誤出現在第8行,第39個字符處。prefixes對象包含了兩個一模一樣的warning屬性,將第二個warning修改為caution。

  這次就不再點擊“JSLint”按鈕,直接看下一個錯誤吧。定義對象的代碼塊的最后多了一個逗號。像這類錯誤,Chrome和Firefox這些瀏覽器也許會忽略,但IE就不會那么友好了,所以我們把這個逗號移除掉。

  之后的兩個錯誤指向未定義的變量concatMsg。如果一個變量在當前作用域中沒有被定義,JavaScript就會全局查找看是否有在別處定義過。若這時你還引入了外部代碼,并碰巧在全局中定義過該變量,那么一旦出錯,你很有可能要抓破頭皮,費盡心力地尋找bug原因。所幸有了JSLint,我們可以將這類錯誤扼殺在搖籃中。

  現在糾正這個錯誤,并重構代碼。因為concatMsg的默認值為msg,所以我們可以將msg先賦給它,待需要時再修改。如下所示,關于concatMsg的代碼為:

1
2
3
4
var concatMsg = msg;
if (type) {
????concatMsg = prefixes[type];
}

  繼續往下,有一個與之前類似的空格問題,糾正它。緊接著,JSLint指出丟失了一個分號(如下圖所示)。JSLint會假設沒有分號結尾的命令行永遠不會被終止。所以,當下面出現if時,JSLint認為這里應該有個分號。盡管根據語言規范,結束的分號可有可無,但是加上它是一個良好的習慣。因為這類不良代碼在大項目協作中很容易引起莫名的bug。所以平常編碼過程中,應順手避免此類問題。

  接下來又是一個很好的錯誤例子。JavaScript中,有‘相等’(==)和嚴格的‘相等’(===)比較。在這段案例代碼中,如果不采用嚴格‘相等’比較,那么不管msg為空字符串還是false值,if內都為true。所以,這里我們采用嚴格‘相等’比較。

  好了,讓我們再次點擊“JSLint”按鈕吧。如下圖所示,錯誤出現在第10行,JSLint認為合并變量聲明也是一個良好的編碼規范。盡管concatMsg變量的聲明緊隨prefixes之后,但JSLint認為用逗號隔開,在一個命令語句中完成變量聲明更好。

  下一個錯誤則又是關于格式的問題。咋一看,不就是多空了一格嘛,實在是太雞毛蒜皮了。但是,如果在大量的腳本中,這種縮進問題搞不好也會引起難以發現的bug。所以,為了代碼的統一性,我們還是往前移一格吧。

  下一個問題又和之前遇到的類似,但形式不一樣。JavaScript的函數也可歸屬為變量,所以和其他變量賦值語句一樣,JSLint希望在末尾加個分號。

  最后,如下所示,有兩個錯誤出現在最后一行。第一個問題,JSLint建議將閉括號移至jQuery之后,因為這樣不會使閉包函數定義產生歧義。第二個問題,JSLint認為jQuery變量不存在。但事實上你可能在實際頁面中已引入了jQuery文件,所以我們可以在頁面最下面的文本框內輸入“jQuery”來解決這個問題(譯者:JSLint Directive上面的文本框)。

  再次運行JSLint,它提示該函數需要接收三個參數。但是在本示例中,我們從未使用過第三個參數。因此,此處我們有兩種方法解決這個問題。第一種,刪除第三個參數。第二種,將下方的“unused parameters”項改為true。如果你確實是因為某些原因需要保留這個參數,則用第二種方法。

  好了,用JSLint改進后的代碼如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(function ($) {
????'use strict';
????$.fn.loading = function (msg, type, cssClass) {
????????var prefixes = {
????????????warning: 'Warning: ' + msg,
????????????error: 'Error: ' + msg,
????????????info: 'Info: ' + msg,
????????????caution: 'Caution: ' + msg
????????}, concatMsg = msg;
????????if (type) {
????????????concatMsg = prefixes[type];
????????}
????????$(this).each(function () {
????????????var tis = $(this);
????????????if (msg === false) {
????????????????tis.html('');
????????????} else {
????????????????tis.html(concatMsg);
????????????}
????????});
????};
}(jQuery));

  JSLint?指令

  你可以通過JSLint指令在你的源代碼中直接定義JSLint變量。這樣,你就不用在頁面上來回操作。如下示例,注釋中定義了jQuery全局變量,并將“unparam”設為true。

1
2
3
4
5
6
/*global jQuery*/
/*jslint unparam: true */
(function ($) {
????‘use strict’;
}(jQuery));

  總結

  在這個簡短的例子中,JSLint指出了一些明顯的和一些容易忽視的錯誤。在實際運行代碼之前,通過JSLint幫我們查找一些錯誤可以有效的提高我們的開發效率和代碼質量。如果你真的是認真地想寫出優質的代碼,那么在放到服務器上運行之前先用JSLint檢查一遍吧。JSLint還提供一個獨立的JS文件版本,所以你也可以把它下載下來在線下運行!

  譯者:

  嚴格模式并不是所有的瀏覽器都支持,這是一個瀏覽器支持統計表。網頁前端可能暫時(甚至很長時間內)還不能遵循嚴格模式,但是在移動開發中顯然采用嚴格模式更佳。不管目前是否能用上,我覺得前端工程師們都應該利用這些工具幫助自己養成良好的編碼習慣,好的習慣會讓你受益匪淺,在這里略矯情略夸張的引用一下電影《鐵娘子》中的一句話:Watch your habits, for they become your character

  英文原文:Using JSLint to Refine Your Code,編譯:伯樂在線 -?胡蓉

轉載于:https://www.cnblogs.com/xuweili/articles/3385322.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273971.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273971.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273971.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pymssql出現的錯誤

安裝pymssql出現的錯誤:如下:---------------------------------------- Failed building wheel for pymssqlRunning setup.py clean for pymssql Failed to build pymssql Installing collected packages: pymssqlRunning setup.py install for pymssq…

javascript設計思維

//一.把參數當作私有變量使用 (function (a, b) {//把參數當作私有變量使用,省略了var,也節省了行數console.log(b) //undefined,所有未賦值的變量均為undefined })(window);//二.把參數作為參數使用 var obj_init function (b, d, f) {//1…

linux第一章簡答

linux第一章簡答題: 1、你在你的主機上面安裝了一張網卡,但是開機之后,系統卻無法使用,你確定網卡是好的,那么可能的問題出在哪里?該如何解決? 答:因為所有的硬件都沒有問題&#xf…

(原創)一個和c#中LazyT類似的c++ LazyT類的實現

在.net 4.0中增加一個延遲加載類Lazy<T>&#xff0c;它的作用是實現按需延遲加載&#xff0c;也許很多人用過。一個典型的應用場景是這樣的&#xff1a;當初始化某個對象時&#xff0c;該對象引用了一個大對象&#xff0c;需要創建&#xff0c;這個對象的創建時需要較長的…

網頁選項卡的應用

&#xff08;1&#xff09;功能描述&#xff1a; 在頁面中&#xff0c;設置三個不同名稱的選項卡&#xff0c;當單機某個選項卡時&#xff0c;下面相對應的區域顯示其內容信息&#xff0c;同時選項卡的背景色與內容信息的背景色渾然一體&#xff0c;并且字體加粗&#xff0c;表…

python 爬蟲-beautifulsoup4

利用它可以不用編寫正則表達式即可方便的實現網頁信息的提取。 pip3 install beautifulsoup4 用法講解&#xff1a;常用解析庫&#xff1a; lxml HTML解析器 lxml XML解析器 from bs4 import BeautifulSoup soup BeautifulSoup(html,lxml) print(soup.prettify()) #格式化代…

魔獸控制命令ID

來源:http://tieba.baidu.com/p/1084211586本次技能ID大全共收錄ID368條不包括重復的ID&#xff0c;物品類技能的ID使用必須將物品技能單獨抽離出來并設置“物品技能false”&#xff0c;擁有命令字符串的物品請參考擁有相同字符串的4族中立技能。P.S所有ID都是按照從小到大的順…

python爬蟲框架--scrapy 基本使用

流程框架&#xff1a; 1、抓取第一頁&#xff1a;請求第一頁的URL并得到源代碼&#xff0c;進行下一步分析。 2、獲取內容和下一頁鏈接&#xff1a;分析源代碼&#xff0c;提取首頁內容&#xff0c;獲取下一頁鏈接等待進一步爬取。 3、保存爬取結果&#xff1a;將爬取結果保存為…

jsp頁面的使用

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取資源文件 InputStream isthis.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Str…

python爬蟲安裝錯誤與解決方式

# 安裝錯誤&#xff1a; error:Microsoft Visual C 14.0 is required... 下載地址&#xff1a;http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted pip install xxx.whl # 運行錯誤 1&#xff1a; from .. Import etree ImportError:DLL load failed pip uninstall lx…

工欲善其事必先利其器系列之:在VS里面折疊js代碼

之前用vs寫js的時候經常因為js代碼過長而且不能像cs文件里面的方法一樣進行折疊而抓狂,直到在擴展庫發現了這款插件有了它就可以把代碼進行折疊了 插件地址轉載于:https://www.cnblogs.com/Chendaqian/p/3396702.html

python- 基礎 map方法

python中map()函數 map()是 Python 內置的高階函數&#xff0c;它接收一個函數 f 和一個 list&#xff0c;并通過把函數 f 依次作用在 list 的每個元素上&#xff0c;得到一個新的 list 并返回。 例如&#xff0c;對于list [1, 2, 3, 4, 5, 6, 7, 8, 9] 如果希望把list的每個…

C算法編程題(二)正螺旋

前言 上一篇《C算法編程題&#xff08;一&#xff09;撲克牌發牌》 寫東西前總是喜歡吐槽一些東西&#xff0c;還是多啰嗦幾句吧&#xff0c;早上看了一篇博文《談談外企漲工資那些事》&#xff0c;里面樓主講到外企公司包含的五類人&#xff0c;其實不只是外企如此&#xff0c…

同時獲取同一等級下多個class值的節點的方法

方法&#xff1a; tr_ soup.find("div", class_"mod_cont fcolor30").find_all("tr", attrs{"class":["md_tr font14 bgcolor-s","md_tr font14 bgcolor"]}) 同時獲取兩個不同的class.例如&#xff1a; 當Beauti…

【循序漸進學Python】6.Python中的函數

1. 創建函數 一個函數代表一個行為并且返回一個結果(包括None)&#xff0c;在Python中使用def關鍵字來定義一個函數&#xff0c;如下&#xff1a; def hello(name):print hello, name ! 接下來調用函數&#xff0c;并查看其返回值&#xff1a; # output: # hello,gy! # None …

求子數組的最大和

窮舉法&#xff1a; int MaxSubArraySum(int a[], int n) { int i, j, MaxSum 0, tmpSum, cnt; for (i1; i<n; i) { for (j0; ji<n; j) { cnt 0; tmpSum 0; while (cnt < i) { tmpSum a[jcnt]; cnt; } if (MaxSum < tmpSum) { MaxSum tmpSum; } } } return Ma…

scrapy框架-post使用

scrapy中使用FormRequest向網頁提交數據 Scrapy post使用 如何post data&#xff1a; http://httpbin.org/post FormRequest : post請求 GitHub Login 借助瀏覽器分析登陸行為。 分析post的內容先嘗試一次錯誤的登陸&#xff1a;如下&#xff1a;分析&#xff1a;需要post…

duilib進階教程 -- 改進窗口拖動 (12)

現在大家應該都知道caption"0,0,0,32"&#xff0c;是指示標題欄區了吧&#xff0c;如果想要整個窗口都能拖動呢&#xff1f; 那直接把高度改成和窗口一樣不就得了~O(∩_∩)O~ 嗯&#xff0c;這樣是可以&#xff0c;比如窗口高度是600&#xff0c;那么我們指定caption…

python- 基礎 range方法的使用

1、第一種用法 index[1,2,0,5,9,8,10,6,4,7] for i in range(len(index)): print(index[i]) 結果&#xff1a; λ py test.py 1 2 0 5 9 8 10 6 4 7 2、第二種用法&#xff1a; index[1,2,0,5,9,8,10,6,4,7] for i in range(0,len(index),2): print(index[i]) 運…

Oracle行列轉換小結

目錄結構如下&#xff1a;行轉列列轉行[一]、行轉列 1.1、初始測試數據 表結構&#xff1a;TEST_TB_GRADE Sql代碼 create table TEST_TB_GRADE ( ID NUMBER(10) not null, USER_NAME VARCHAR2(20 CHAR), COURSE VARCHAR2(20 CHAR), SCORE FLOAT ) 初始…