首頁  >  文章  >  web前端  >  我的NodeJs學習小結(一)_node.js

我的NodeJs學習小結(一)_node.js

WBOY
WBOY原創
2016-05-16 16:42:311166瀏覽

 這第一篇就來談談NodeJs的一些程式細節吧。

1、遍歷數組

for (var i=0, l=arr.length; i<l; i++)

      如此寫的好處是讓每次循環少一步取得陣列物件長度的操作,陣列長度越長,價值越明顯。

2、判斷變數的真假

if (a) {...} //a='', a='0', a=[], a={}

      if條件判斷的結果分別為:false, true, true, true。這個結果和PHP的結果是不同的,不要混淆。還需要區分它和非恆等判斷相似的情況。

3、0值非恆等判斷

1 if (0 == '0') {...} //true
2 if (0 == []) {...} //true
3 if (0 == [0]) {...} //true
4 if (0 == {}) {...} //false
5 if (0 == null) {...} //false
6 if (0 == undefined) {...} //false

      其實還有很多這種詭異的判斷,我只列出了較為常見的。如果想弄清楚其中的規則,請參考我的另一篇部落格文章:【JavaScript】深入分析JavaScript的關係運算和if語句。

4、parseInt的陷阱

var n = parseInt(s); //s='010'

        此語句執行後n值為8,而非10。雖然很多人知道這一點,但是程式設計中難免會出錯,我深有體會。所以,最好用下面的方式來寫,就不會出錯了。

var n = parseInt(s, 10);

5、變數在使用前一定要先宣告

      雖然,直接使用變數而不宣告也不會出錯,但是,這樣寫是很容易出錯的。因為解釋器會把它解釋成全域變量,很容易和其他全域變數重名而導致出錯。所以,一定要養成變數使用前要先聲明的好習慣。

6.循環中存在非同步的情況

for (var i=0, l=arr.length; i<l; i++) {
   var sql = "select * from nx_user";
  db.query(sql, function(){
    sys.log(i + ': ' + sql);
  }); //db.query为表查询操作,是异步操作
}

      你會發現,輸出的結果都是相同的,而且是當i=arr.length-1時的輸出內容。因為JavaScript是單執行緒的,它會先執行完整個迴圈的同步內容之後,才會去執行其中的非同步操作。程式碼中的匿名回呼函數就是一個非同步回呼。執行到該函數的時候,for迴圈以及後面的一些同步操作都已經執行完畢。出於閉包原則,函數會保留for迴圈的最後一次迴圈的sql變數和i變數的內容,所以才會導致錯誤的結果。

      那該怎麼辦呢?解決方法有兩種,一種是使用立即函數,如下:

for (var i=0, l=arr.length; i<l; i++) {
  var sql = "select * from nx_user";
  (function(sql, i){
    db.query(sql, function(){
      sys.log(i + ': ' + sql);
    }); //db.query为表查询操作,是异步操作
  })(sql, i);
}

       還有一個方法是將非同步操作部分提取出來,單寫一個函數,如下:

var outputSQL = function(sql, i){
   db.query(sql, function(){
      sys.log(i + ': ' + sql);
  }); //db.query为表查询操作,是异步操作
}

for (var i=0, l=arr.length; i<l; i++) {
  var sql = "select * from nx_user";
  outputSQL(sql, i); 
}


7 、在對大量資料作處理時,盡量避免循環巢狀。

      因為循環巢狀的處理時間會隨著資料量的增加而呈指數級增長,所以應盡量避免。遇到這種情況,如果沒有更好的辦法,一般採取的策略是以空間換時間,也就是建立一張二級循環資料的Hash映射表。當然,還要具體情況具體分析。還有一點要說的是,某些方法本身就是一個循環體,如Array.sort()(該方法應該是用了兩層循環實作),在使用的時候需加註意。

8、盡量避免遞迴呼叫。

      遞歸呼叫的優點是程式碼簡潔,實作簡單,而它的缺點很重要,說明如下:

      (1)函數棧的大小會隨著遞歸層次成線性增長,而函數棧是有上限值的,當遞歸達到一定層數後函數棧就會溢出,從而導致程式出錯;

      (2)每遞歸一層都會增加額外的壓棧和出棧操作,即函數呼叫過程中的保存現場和恢復現場。

      所以,應盡量避免遞歸呼叫。

9.關於模組檔案的作用域隔離。

      Node在編譯JavaScript模組檔案的時候,已經對其內容進行了頭尾包裝,如下:

(function(exports, require, module, __filename, __dirname){
  你的JavaScript文件代码
});

從而使每個模組檔案之間進行了作用域隔離。所以,當你寫NodeJs模組檔案的時候,不需要自己再加一層作用域隔離封裝了。如下面的程式碼格式,只會額外增加一層函數調用,是不建議的:

(function(){
  ... ...
})();

 10、陣列和物件不要混用

      以下是錯誤代碼的範例:

var o = [];
o['name'] = 'LiMing';

      陣列和物件混用可能會導致不可預測的錯誤。我的一個同事就遇到一個很奇怪的問題,先看程式碼:

var o = [];
o['name'] = 'LiMing';
var s = JSON.stringify(o);

       他以為物件o的name屬性會在JSON串中,結果就是沒有。當時我也很奇怪,但我有預感到是數組和物件混用的問題,試了一下,果然是它的問題。後來我在ECMA規範中查到,數組在序列化時是依照JA規則進行的。所以,要養成一個好的程式設計習慣,正確使用陣列和對象,不要混用。

11、promise優雅程式

       相信接觸過nodeJs的人都有這樣的體驗,當異步回呼裡嵌套非同步回呼的時候,程式碼就顯得很混亂,缺乏易讀性。 nodeJs的這一窘境可以藉助promise來克服。 promise就像一個雕琢器,讓你的程式碼變得優雅、美觀。 promise有個A 規範,網路上有幾種實作方式,可以參考。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn