日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
編寫更加穩(wěn)定、可讀性強的JavaScript代碼

每個人都有自己的編程風(fēng) 格,也無可避免的要去感受別人的編程風(fēng)格——修改別人的代碼?!毙薷膭e人的代碼”對于我們來說的一件很痛苦的事情。因為有些代碼并不是那么容易閱讀、可維 護的,讓另一個人來修改別人的代碼,或許最終只會修改一個變量,調(diào)整一個函數(shù)的調(diào)用時機,卻需要花上1個小時甚至更多的時間來閱讀、縷清別人的代碼。本文 一步步帶你重構(gòu)一段獲取位置的”組件”——提升你的javascript代碼的可讀性和穩(wěn)定性。

公司主營業(yè)務(wù):成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出張北免費做網(wǎng)站回饋大家。

  本文內(nèi)容如下:

  • 分離你的javascript代碼

  • 函數(shù)不應(yīng)該過分依賴外部環(huán)境

  • 語義化和復(fù)用

  • 組件應(yīng)該關(guān)注邏輯,行為只是封裝

  • 形成自己的風(fēng)格的代碼

 分離你的javascript代碼

  下面一段代碼演示了難以閱讀/修改的代碼:

 
 
  1. (function (window, namespace) {
  2.     var $ = window.jQuery;
  3.     window[namespace] = function (targetId, textId) { //一個嘗試復(fù)用的獲取位置的"組件" var $target = $('#' + targetId),//按鈕 $text = $('#' + textId);//顯示文本 $target.on('click', function () { $text.html('獲取中'); var data = '北京市';//balabala很多邏輯,偽代碼,獲取得到位置中
  4.             if (data) {
  5.                 $text.html(data);
  6.             } else
  7.                 $text.html('獲取失敗');
  8.         });
  9.     }
  10. })(window, 'linkFly');

  這一段代碼,我們暫且認(rèn)可它已經(jīng)構(gòu)成一個”組件”。
上面的代碼就是典型的一個方法搞定所有事情,一旦填充上內(nèi)部的邏輯就會變得生活不能自理,而一旦增加需求,例如獲取位置返回的數(shù)據(jù)格式需要加工,那么就要去里面尋找處理數(shù)據(jù)的代碼然后修改。

  我們分離一下邏輯,得到代碼如下:

 
 
  1. (function (window, namespace) {
  2.     var $ = window.jQuery,
  3.         $target,
  4.         $text,
  5.         states= ['獲取中', '獲取失敗'];
  6.     function done(address) {//獲取位置成功
  7.         $text.html(address);
  8.     }
  9.     function fail() {
  10.         $text.html(states[1]);
  11.     }
  12.     function checkData(data) {
  13.         //檢查位置信息是否正確
  14.         return !!data;
  15.     }
  16.     function loadPosition() {
  17.         var data = '北京市';//獲取位置中
  18.         if (checkData(data)) {
  19.             done(data);
  20.         } else
  21.             fail();
  22.     }
  23.     var init = function () {
  24.         $target.on('click', function () {
  25.             $text.html(states[0]);
  26.             loadPosition();
  27.         });
  28.     };
  29.     window[namespace] = function (targetId, textId) {
  30.         $target = $('#' + targetId);
  31.         $text = $('#' + textId);
  32.         initData();
  33.         setData();
  34.     }
  35. })(window, 'linkFly');

 函數(shù)不應(yīng)該過分依賴外部環(huán)境

  上面的代碼中,我們已經(jīng)把整個組件,切割成了各種函數(shù)(注意這里我說的是函數(shù),不是方法),這里常出現(xiàn)一個新的問題:函數(shù)過分依賴不可控的變量。

  變量$target和$text身為環(huán)境中的全局變量,從組件初始化便賦值,而我們切割后的代碼大多數(shù)的操作方法都依賴$text,尤其是$text和done()、fail()之間曖昧的關(guān)系,一旦$text相關(guān)的結(jié)構(gòu)、邏輯改變,那么我們的代碼將會進行不小的改動。

  和頁面/DOM相關(guān)的都是不可信賴的(例如$target和$text),一旦頁面結(jié)構(gòu)發(fā)生改變,它的行為很大程度上也會隨之改變。而函數(shù)也不應(yīng)該依賴外部的環(huán)境。
在不可控的變量上,我們應(yīng)該解開函數(shù)和依賴變量上的關(guān)系,讓函數(shù)變得更加專注自己區(qū)域的邏輯,更加的純粹。簡單的說:函數(shù)所依賴的外部變量,都應(yīng)該通過參數(shù)傳遞到函數(shù)內(nèi)部。
新的代碼如下:

 
 
  1. (function (window, namespace) {
  2.     var $ = window.jQuery;
  3.     //檢查位置信息是否正確
  4.     function checkData(data) {
  5.         return !!data;
  6.     }
  7.     //獲取位置中
  8.     function loadPosition(done, fail) {
  9.         var data = '北京市';//獲取位置中
  10.         if (checkData(data)) {
  11.             done(data);
  12.         } else
  13.             fail();
  14.     }
  15.     window[namespace] = function (targetId, textId) {
  16.        var  $target = $('#' + targetId),
  17.             $text = $('#' + textId);
  18.         var states = ['獲取中', '獲取失敗'];
  19.         $target.on('click', function () {
  20.             $text.html(states[0]);
  21.             loadPosition(function (address) {//獲取位置成功
  22.                 $text.html(address);
  23.             }, function () {//獲取位置失敗
  24.                 $text.html(states[1]);
  25.             });
  26.         });
  27.     }
  28. })(window, 'linkFly');

 語義化和復(fù)用

  變量states是一個數(shù)組,它描述的行為難以閱讀,每次看到states[0]都有一種分分鐘想捏死原作者的沖動,因為我們總是要記住變量states的值,在代碼上,我們應(yīng)該盡可能讓它可以很好的被閱讀。

  另外,上面的代碼中$text.html就是典型的代碼重復(fù),我們再一次的修改代碼,請注意這一次修改的代碼中,我們所抽離的changeStateText()的代碼位置,它并沒有被提升到上一層環(huán)境中(也就是整個大閉包的環(huán)境)。

 
 
  1. (function (window, namespace) {
  2.     var $ = window.jQuery;
  3.     function checkData(data) {
  4.         return !!data;
  5.     }
  6.     function loadPosition(done, fail) {
  7.         var data = '北京市';//獲取位置中
  8.         if (checkData(data)) {
  9.             done(data);
  10.         } else
  11.             fail();
  12.     }
  13.     window[namespace] = function (targetId, textId) {
  14.         var $target = $('#' + targetId),
  15.             $text = $('#' + textId),
  16.             changeEnum = { LOADING: '獲取中', FAIL: '獲取失敗' },
  17.             changeStateText = function (text) {
  18.                 $text.html(text);
  19.             };
  20.         $target.on('click', function () {
  21.             changeStateText(changeEnum.LOADING);
  22.             loadPosition(function (address) {
  23.                 changeStateText(address);
  24.             }, function () {
  25.                 changeStateText(changeEnum.FAIL);
  26.             });
  27.         });
  28.     }
  29. })(window, 'linkFly');

  提及語義化,我們必須要知道當(dāng)前整個代碼的邏輯和語義:

  在這整個組件中,所有的函數(shù)模塊可以分為:工具和工具提供者。

  上一層環(huán)境(整個大閉包)在我們的業(yè)務(wù)中扮演著工具的身份,它的任務(wù)是締造一套和獲取位置邏輯相關(guān)的工具,而在window[namespace])函數(shù)中,則是工具提供者的身份,它是唯一的入口,負(fù)責(zé)提供組件完整的業(yè)務(wù)給工具的使用者。
這里的$text.html()在邏輯上并不屬于工具,而是屬于工具提供者使用工具后所得到的反饋,所以changeStateText()函數(shù)置于工具提供者window[namespace]()中。

 組件應(yīng)該關(guān)注邏輯,行為只是封裝

  到此為止,我們分離了函數(shù),并讓這個組件擁有了良好的語義。但這時候來了新的需求:當(dāng)沒有獲取到位置的時候,需要進行一些其他的操作。這時候會發(fā)現(xiàn),我們需要window[namespace]()上加上新的參數(shù)。

  當(dāng)我們加上新的參數(shù)之后,又被告知新的需求:當(dāng)獲取位置失敗了之后,需要修改一些信息,然后再次嘗試獲取位置信息。

  不過幸好,我們的代碼已經(jīng)把大部分的邏輯抽離到了工具提供者中了,對整個工具的邏輯影響并不大。

  同時我們再看看代碼就會發(fā)現(xiàn)我們的組件除了工具提供者之外,沒有方法(依賴在對象上的函數(shù))。也就是說,我們的組件并沒有對象。

  我見過很多人的代碼總是喜歡打造工具提供者,而忽略了工具的本質(zhì)。迎合上面的增加的需求,那么我們的工具提供者將會變得越來越重,這時候我們應(yīng)該思考到:是不是應(yīng)該把工具提供出去?

  讓我們回到最初的需求——僅僅只是一個獲取位置的組件,沒錯,它的核心業(yè)務(wù)就是獲取位置——它不應(yīng)該被組件化。它的本質(zhì)應(yīng)該是個工具對象,而不應(yīng)該和頁面相關(guān),我們從一開始就不應(yīng)該關(guān)注頁面上的變化,讓我們重構(gòu)代碼如下:

 
 
  1. (function (window, namespace) {
  2.     var Gps = {
  3.         load: function (fone, fail) {
  4.             var data = '北京市';//獲取位置偽代碼
  5.             this.check(data) ?
  6.                 done(data, Gps.state.OK) :
  7.                 fail(Gps.state.FAIL);
  8.         },
  9.         check: function (data) {
  10.             return !!data;
  11.         },
  12.         state: { OK: 1, FAIL: 0 }
  13.     };
  14.     window[namespace] = Gps;
  15. })(window, 'Gps');

  在這里,我們直接捏死了工具提供者,我們直接將工具提供給外面的工具使用者,讓工具使用者直接使用我們的工具,這里的代碼無關(guān)狀態(tài)、無關(guān)頁面。

  至此,重構(gòu)完成。

 形成自己風(fēng)格的代碼

  之所以講這個是因為大家都有自己的編程風(fēng)格。有些人的編程風(fēng)格就是開篇那種代碼的…

  我覺得形成自己的編程風(fēng)格,是建立在良好代碼的和結(jié)構(gòu)/語義上的。否則只會讓你的代碼變得越來越難讀,越來越難寫。

  ****

  單var和多var

  我個人是喜歡單var風(fēng)格的,不過我覺得代碼還是盡可能在使用某一方法/函數(shù)使用前進行var,有時候甚至于為了單var而變得喪心病狂:由于我又過分的喜愛函數(shù)表達(dá)式聲明,函數(shù)表達(dá)式聲明并不會在var語句中執(zhí)行,于是偶爾會出現(xiàn)這種邊聲明邊執(zhí)行的代碼,為了不教壞小朋友就不貼代碼了(我不會告訴你們其實是我找不到了)。

  對象屬性的屏蔽

  下面的代碼演示了兩種對象的構(gòu)建,后一種通過閉包把內(nèi)部屬性隱藏,同樣,兩種方法都實現(xiàn)了無new化,我個人…是不喜歡看見很多this的..但還是推薦前者。

 
 
  1. (function () {
  2.     //第一種,曝露了_name屬性
  3.     var Demo = function () {
  4.         if (!(this instanceof Demo))
  5.             return new Demo();
  6.         this._name = 'linkFly';
  7.     };
  8.     Demo.prototype.getName = function () {
  9.         return this._name;
  10.     }
  11.     //第二種,多一層閉包意味內(nèi)存消耗更大,但是屏蔽了_name屬性
  12.     var Demo = function () {
  13.         var name = 'linkFly';
  14.         return {
  15.             getName: function () {
  16.                 return name;
  17.             }
  18.         }
  19.     }
  20. });

  巧用變量置頂[hoisting]

  巧用函數(shù)聲明的變量置頂特性意味著處女座心態(tài)的你放棄單var,但卻可以讓你的函數(shù)在代碼結(jié)構(gòu)上十分清晰,例如下面的代碼:

 
 
  1. (function () {
  2.     var names = [];
  3.     return function (name) {
  4.         addName(name);
  5.     }
  6.     function addName(name) {
  7.         if (!~names.indexOf(name))//如果存在則不添加
  8.             names.push(name);
  9.         console.log(names);// ["linkFly"]
  10.     }
  11. }())('linkFly');
  12.   if和&&

  這種代碼,在幾個群里都見過討論:

 
 
  1. (function () {
  2.     var key = 'linkFly',
  3.         cache = { 'linkFly': 'http://www.cnblogs.com/silin6/' },
  4.         value;
  5.     //&&到底
  6.     key && cache && cache[key] && (value = cache[key]);
  7.     //來個if
  8.     if (key && cache && cache[key])
  9.         value = cache[key];
  10. })();

  大概就想到這么些了,我突然發(fā)現(xiàn)我不太推薦的代碼,都是我寫的代碼,囧。如果各位也還有更多有趣的代碼,希望各位看官能掏出來讓小弟見識見識。


當(dāng)前題目:編寫更加穩(wěn)定、可讀性強的JavaScript代碼
分享URL:http://www.5511xx.com/article/dhisjpi.html