高程3總結#第24章最佳實踐

最佳實踐

可維護性

什麼是可維護性的代碼

  • 若是說代碼是可維護的,它須要遵循如下特色javascript

    • 可理解性——其餘人能夠接手代碼並理解它的意圖和通常途徑,而無需原開發人員的完整解釋。
    • 直觀性——代碼中的東西一看就能明白,無論其操做過程多麼複雜。
    • 可適應性——代碼以一種數據上的變化不要求徹底重寫的方法撰寫。
    • 可擴展性——在代碼架構上已考慮到在將來容許對核心功能進行擴展
    • 可調試性——當有地方出錯時,代碼能夠給予你足夠的信息來儘量直接地肯定問題所在。

代碼約定

可讀性

  • 可讀性大部份內容和代碼的縮進相關,當全部人使用同樣的縮進方式時,整個項目的代碼都會更加易於閱讀
  • 可讀性的另外一方面是註釋,下面內容須要進行註釋php

    • 函數和方法——每一個函數或方法都應該包含一個註釋,描述其目的和用於完成任務所可能使用的算法。陳述事先的假設也很是重要,如參數表明什麼,函數是否有返回值(由於這不能從函數定義中推斷出來)。
    • 大段代碼——用於完成單個任務的多行代碼應該在前面放一個描述任務的註釋。
    • 複雜的算法——若是使用了一種獨特的方式解決某個問題,則要在註釋中解釋你是如何作的。這不只僅能夠幫助其餘瀏覽你代碼的人,也能在下次你本身查閱代碼的時候幫助理解。
    • Hack——由於存在瀏覽器差別,JavaScript 代碼通常會包含一些 hack。不要假設其餘人在看代碼的時候可以理解 hack 所要應付的瀏覽器問題。若是由於某種瀏覽器沒法使用普通的方法,因此你須要用一些不一樣的方法,那麼請將這些信息放在註釋中。這樣能夠減小出現這種狀況的可能性:有人偶然看到你的 hack,而後「修正」了它,最後從新引入了你原本修正了的錯誤。

變量和函數命名

  • 命名規則html

    • 變量名應爲名詞如 car 或 person 。
    • 函數名應該以動詞開始,如 getName() 。返回布爾類型值的函數通常以 is 開頭,如isEnable() 。
    • 變量和函數都應使用合乎邏輯的名字,不要擔憂長度。長度問題能夠經過後處理和壓縮來緩解

變量類型透明

  • 三種表示變量數據類型的方式java

    • 初始化算法

      //經過初始化指定變量類型
      var found = false; //布爾型
      var count = -1; //數字
      var name = ""; //字符串
      var person = null; //對象
    • 使用匈牙利標記法編程

      //用於指定數據類型的匈牙利標記法
      var bFound; //布爾型
      var iCount; //整數
      var sName; //字符串
      var oPerson; //對象
    • 使用類型註釋數組

      //用於指定類型的類型註釋
      var found /*:Boolean*/ = false;
      var count /*:int*/ = 10;
      var name /*:String*/ = "Nicholas";
      var person /*:Object*/ = null

鬆散耦合

  • 幾條規則瀏覽器

    • 勿將 event 對象傳給其餘方法;只傳來自 event 對象中所需的數據;
    • 任何能夠在應用層面的動做都應該能夠在不執行任何事件處理程序的狀況下進行;
    • 任何事件處理程序都應該處理事件,而後將處理轉交給應用邏輯

編程實踐

尊重對象全部權

  • 不要爲實例或原型添加屬性;
  • 不要爲實例或原型添加方法;
  • 不要重定義已存在的方法。
  • 建立包含所需功能的新對象,並用它與相關對象進行交互;
  • 建立自定義類型,繼承須要進行修改的類型。而後能夠爲自定義類型添加額外功能。

避免全局量

//兩個全局量——避免!!
var name = "Nicholas";
function sayName(){
alert(name);
}
//一個全局量——推薦
var MyApplication = {
name: "Nicholas",
sayName: function(){
  alert(this.name);
}
}

避免與null進行比較

function sortArray(values){
if (values != null){ //避免!
  values.sort(comparator);
}
}
function sortArray(values){
if (values instanceof Array){ // 推薦
  values.sort(comparator);
}
}
  • 若是看到了與null比較的代碼,嘗試使用如下技術替換安全

    • 若是值應爲一個引用類型,使用 instanceof 操做符檢查其構造函數;
    • 若是值應爲一個基本類型,使用 typeof 檢查其類型;
    • 若是是但願對象包含某個特定的方法名,則使用 typeof 操做符確保指定名字的方法存在於對象上。

使用常量

var Constants = {
INVALID_VALUE_MSG: "Invalid value!",
INVALID_VALUE_URL: "/errors/invalid.php"
};
function validate(value){
if (!value){
  alert(Constants.INVALID_VALUE_MSG);
  location.href = Constants.INVALID_VALUE_URL;
}
}

性能

注意做用域

避免全局查找

function updateUI(){
var imgs = document.getElementsByTagName("img");
for (var i=0, len=imgs.length; i < len; i++){
  imgs[i].title = document.title + " image " + i;
}
var msg = document.getElementById("msg");
msg.innerHTML = "Update complete.";
}
//改進
function updateUI(){
var doc = document;
var imgs = doc.getElementsByTagName("img");
for (var i=0, len=imgs.length; i < len; i++){
  imgs[i].title = doc.title + " image " + i;
}
var msg = doc.getElementById("msg");
msg.innerHTML = "Update complete.";
}

避免with語句

function updateBody(){
with(document.body){
  alert(tagName);
  innerHTML = "Hello world!";
}
}
//改進
function updateBody(){
var body = document.body
alert(body.tagName);
body.innerHTML = "Hello world!";
}

選擇正確方法

避免沒必要要的屬性查找

圖片描述

優化循環

  • 減值迭代——大多數循環使用一個從 0 開始、增長到某個特定值的迭代器。在不少狀況下,從最大值開始,在循環中不斷減值的迭代器更加高效。
  • 簡化終止條件——因爲每次循環過程都會計算終止條件,因此必須保證它儘量快。也就是說避免屬性查找或其餘 O(n)的操做。
  • 簡化循環體——循環體是執行最多的,因此要確保其被最大限度地優化。確保沒有某些能夠被很容易移出循環的密集計算。
  • 使用後測試循環——最經常使用 for 循環和 while 循環都是前測試循環。而如 do-while 這種後測試循環,能夠避免最初終止條件的計算,所以運行更快

展開循環

//credit: Speed Up Your Site (New Riders, 2003)
var iterations = Math.floor(values.length / 8);
var leftover = values.length % 8;
var i = 0;
if (leftover > 0){
do {
  process(values[i++]);
} while (--leftover > 0);
}
do {
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
process(values[i++]);
} while (--iterations > 0);

避免雙重解釋

//某些代碼求值——避免!!
eval("alert('Hello world!')");
//建立新函數——避免!!
var sayHi = new Function("alert('Hello world!')");
//設置超時——避免!!
setTimeout("alert('Hello world!')", 500);
//已修正
alert('Hello world!');
//建立新函數——已修正
var sayHi = function(){
alert('Hello world!');
};
//設置一個超時——已修正
setTimeout(function(){
alert('Hello world!');
}, 500);

其餘

  • 原生方法較快——只要有可能,使用原生方法而不是本身用 JavaScript 重寫一個。原生方法是用諸如 C/C++之類的編譯型語言寫出來的,因此要比 JavaScript 的快不少不少。JavaScript 中最容易被忘記的就是能夠在 Math 對象中找到的複雜的數學運算;這些方法要比任何用 JavaScript 寫的一樣方法如正弦、餘弦快的多。
  • Switch 語句較快 —— 若是有一系列複雜的 if-else 語句,能夠轉換成單個 switch 語句則能夠獲得更快的代碼。還能夠經過將 case 語句按照最可能的到最不可能的順序進行組織,來進一步優化 switch 語句。
  • 位運算符較快 —— 當進行數學運算的時候,位運算操做要比任何布爾運算或者算數運算快。選擇性地用位運算替換算數運算能夠極大提高複雜計算的性能。諸如取模,邏輯與和邏輯或均可以考慮用位運算來替換

最小化語句數

多個變量聲明

//4 個語句 —— 很浪費
var count = 5;
var color = "blue";
var values = [1,2,3];
var now = new Date()
//改進
//一個語句
var count = 5,
  color = "blue",
  values = [1,2,3],
  now = new Date()

插入迭代值

var name = values[i];
i++;
//改進
var name = values[i++];

使用數組和對象字面量

//用 4 個語句建立和初始化數組——浪費
var values = new Array();
values[0] = 123;
values[1] = 456;
values[2] = 789;
//用 4 個語句建立和初始化對象——浪費
var person = new Object();
person.name = "Nicholas";
person.age = 29;
person.sayName = function(){
alert(this.name);
};
//改進
//只用一條語句建立和初始化數組
var values = [123, 456, 789];
//只用一條語句建立和初始化對象
var person = {
name : "Nicholas",
age : 29,
sayName : function(){
  alert(this.name);
}
};

優化DOM交互

最小化現場更新

var list = document.getElementById("myList"),
  fragment = document.createDocumentFragment(),
  item,
  i;
for (i=0; i < 10; i++) {
item = document.createElement("li");
fragment.appendChild(item);
item.appendChild(document.createTextNode("Item " + i));
}
list.appendChild(fragment);

使用innerHTML

var list = document.getElementById("myList"),
  html = "",
  i;
for (i=0; i < 10; i++) {
html += "<li>Item " + i + "</li>";
}
list.innerHTML = html;

使用事件代理

HTMLCollection

var images = document.getElementsByTagName("img"),
  image,
  i, len;
for (i=0, len=images.length; i < len; i++){
image = images[i];
//處理
}

部署

構建過程

  • 寫的代碼不該該原封不動地放入瀏覽器中服務器

    • 知識產權問題 —— 若是把帶有完整註釋的代碼放到線上,那別人就更容易知道你的意圖,對它再利用,而且可能找到安全漏洞。
    • 文件大小 —— 書寫代碼要保證容易閱讀,才能更好地維護,可是這對於性能是不利的。瀏覽器並不能從額外的空白字符或者是冗長的函數名和變量名中得到什麼好處。
    • 代碼組織 —— 組織代碼要考慮到可維護性並不必定是傳送給瀏覽器的最好方式。

驗證

  • JSLint能夠查找JavaScript代碼中語法錯誤以及常見的編碼錯誤,能夠發掘潛在問題

    • eval() 的使用;
    • 未聲明變量的使用;
    • 遺漏的分號;
    • 不恰當的換行;
    • 錯誤的逗號使用;
    • 語句周圍遺漏的括號;
    • switch 分支語句中遺漏的 break ;
    • 重複聲明的變量;
    • with 的使用;
    • 錯誤使用的等號(替代了雙等號或三等號);
    • 沒法到達的代碼。

壓縮

文件壓縮

  • 刪除額外的空白(包括換行);
  • 刪除全部註釋;
  • 縮短變量名。

HTTP壓縮

  • 對於 Apache Web服務器,有兩個模塊能夠進行 HTTP壓縮: mod_gzip (Apache1.3.x)和 mod_deflate(Apache 2.0.x)。對於 mod_gzip ,能夠給 httpd.conf 文件或者是 .htacces s文件添加如下代碼啓用對JavaScript的自動壓縮:

    告訴 mod_zip 要包含任何以.js 結尾的文件
    mod_gzip_item_include file \.js$
相關文章
相關標籤/搜索