Node.js學習筆記(二)

今天的內容涉及Node的原理、運行機制和CommonJS的內容,會有點沉悶,也會有點困難,建議像我同樣作一些筆記。

模塊

在開發大型應用的時候,咱們經常會用到全局變量,例如:var s="Hello"。可是,當咱們的應用愈來愈大時,咱們可能會不當心重複用了幾個相同的變量或者函數名,這就會給咱們的應用形成麻煩。爲了解決這個困難,因而提出了模塊的概念。模塊是一種代碼的組織形式,就是把實現不一樣功能的JS代碼分開來寫,把相同名字的函數或變量存在不一樣的模塊中,這樣就能夠避免相同名的函數或變量發生衝突了。編程

同時,模塊還能夠提升代碼的可維護性。由於你只要關心寫好當前的模塊,而沒必要擔憂會污染或影響到別的模塊,模塊之間都是隔離的。數組

在上一節的例子中,咱們編寫了一個hello.js的代碼。在這裏,咱們把它修改一下:閉包

'use strict';

var s="Hello";

function greet(name){
  console.log(s + "," + name + "!");
}

module.exports=greet;

這裏,咱們用module.exports向外輸出了一個變量。這個變量就是這個模塊與外界的一個出口。這個變量能夠是函數、對象、數組編程語言

既然有輸出,就要有接口。咱們再建立一個main.js:函數式編程

'use strict';

//引入hello模塊:
var heat=require('./hello');
var s='Michael';

heat(s);   //Hello,Michael!

這裏,咱們用require函數引入了hello模塊。main.js中,變量heat就是在hello.js中暴露的greet函數。接下來heat(s)`就是直接使用它了。函數

Commonjs規範和Node的內部運行

這種模塊加載的方式被稱爲Commonjs規範,除了這種規範以外,還有ES六、AMD、CMD,這裏不細談,我也還沒學到,這裏只談談Commonjs和之前學的閉包知識。網站

在上文中,咱們提到了全局變量的衝突。正如咱們在上面的例子中,兩個js文件都聲明瞭變量s,可是並無發生衝突,仍然是按照咱們的意願來執行的,這就是Node實行了模塊的隔離。ui

隔離的原理

Node可以實現模塊和變量的隔離,是由於閉包。

JS是一種函數式編程語言,它支持閉包,若是咱們用函數把某個變量包起來,這個變量就變成了函數內部的局部變量了。而咱們知道,閉包中只要這個函數的生命週期沒有結束,這個變量也就能夠一直存在,而不會受到其餘函數外的其餘變量的影響。code

咱們以上面的例子來解釋,在hello模塊中,s="hello"被保存了起來,只對外開了一個口:module.exports=greet,在函數greet中,包含有變量s,因此」s=hello」能一直被保存起來,直到greet在main模塊中被引用。對象

這裏有一個問題,咱們說須要一個函數才能造成閉包,可是咱們的代碼並無這個函數呀?這就是Node作的工做了,Node幫咱們在內部包裝了hello模塊:

(function(){
  var s="Hello";
  function greet(name){
    console.log(s + "," + name + "!");
  }
})()

所以,s就變成了匿名函數的內部局部變量,後來加載的其餘模塊中即便也有s變量,也不會影響到這個s變量。

模塊的輸出

在Node中有一個module對象,讓咱們來看看模塊的輸出過程:

var module={
  id:'hello',
  exports:{}
};
var load=function(module){
  //讀取的hello.js代碼
  function greet(name){
    console.log( "Hello," + name + "!");
  }
  module.exports=greet;
  //hello.js代碼結束
  return module.exports;
};
var exported=load(module);
//保存module
save(module,exported);

在咱們的hello模塊中,咱們經過module.exports=greet把一個變量傳給了Node,而module其實是Node準備階段的一個變量,並且也是做爲load函數的一個參數被保存了下來。每當咱們使用module.exports時,Node就把一條module按模塊分類存了起來,這些module都被保存在了一塊兒。

當咱們在main模塊中想要用到hello模塊時,咱們又使用require()來讓Node幫咱們在找到id爲hello的module傳遞給咱們。這樣,咱們就拿到了hello的模塊輸出。

Node的運行參考了 模塊—廖雪峯的官方網站,實在看的我也有點繞,不過Node處理模塊的運行原理咱們如今看個大概暫時就夠了,等學完主體內容再來細細分析。

兩種輸出方式

咱們能夠經過兩種方式輸出模塊:

方法一:

module.exports={
  hello:hello,
  greet:greet
}

方法二:

exports.hello=hello;
exports.greet=greet;

可是你不能直接對exports賦值:

exports={
  hello:hello,
  greet:greet
}
實踐證實,使用 module.exports=xxx的方式賦值更好。具體緣由一樣涉及到Node的內部處理。有興趣的同窗能夠參考上面的那篇文章。
相關文章
相關標籤/搜索