node.js - 基礎(chǔ)之module

nodejs-exports.jpg

1. node.js模塊概述

為了讓node.js的文件可以相互調(diào)用,node.js提供了一個簡單的模塊系統(tǒng)。模塊是node.js應(yīng)用程序基本的組成部分,文件和模塊是一一對應(yīng)的。換言之,一個node.js文件就是一個模塊,這個文件可能是javascript代碼、json或者編譯過的c/c++擴展。

其中http、fs、net等都是node.js提供的核心模塊,使用c/c++實現(xiàn),外部用javascript封裝。

2. 創(chuàng)建模塊的兩種方式

創(chuàng)建模塊有兩種方式,

  • 通過exports創(chuàng)建
  • 通過module.exports創(chuàng)建

2.1 通過exports創(chuàng)建模塊

node.js中,創(chuàng)建一個模塊非常簡單,我們創(chuàng)建一個main.js文件,它引用了hello模塊,代碼如下,

var hello = require('./hello')
hello.world()

在上面的代碼中,require('./hello')引入了當(dāng)前目錄下的hello.js文件。

./代表當(dāng)前目錄,node.js默認(rèn)后綴為js。

node.js提供了exportsrequire兩個對象,其中exports是模塊公開的接口,require用于從外部獲取一個模塊的接口,即所獲取模塊的exports對象。

接下來我們創(chuàng)建hello.js文件,如下代碼所示,

exports.world = function() {
  console.log('hello world')
}

以上示例中,hello.js通過exports對象把world作為模塊的訪問接口,在main.js中通過require('./hello')加載這個模塊,然后就可以直接訪問hello.js中exports對象的成員函數(shù)了。

2.2 通過module.exports創(chuàng)建模塊

有時候我們只是想把一個對象封裝到模塊中,如下格式,

module.exports = function() {
    
}

以上面的格式,來寫一個模塊,如下hello.js代碼,

function Hello() {
    var name;
    this.setName = function(thyName) {
        name = thyName
    }
    
    this.sayHello = function() {
        console.log('hello ' + name)
    }
}

module.exports = Hello

這樣就可以直接獲取這個對象了,如下main.js代碼,

// main.js
var Hello = require('./hello')
hello = new Hello()
hello.setName('BYVoid')
hello.sayHello()

模塊接口的唯一變化是使用module.exports = Hello代替了exports.world = function() {}。在外部引用該模塊時,其接口對象就是要輸出的Hello對象本身,而不是原先的exports。

2.3 exports和module.exports區(qū)別

為了更好地解釋exports和module.exports之間的關(guān)系,先通過一個簡單的js示例來做一個說明,如下代碼,

var a = {name: 1}
var b = a

console.log(a)
console.log(b)

b.name = 2
console.log(a)
console.log(b)

b = {name: 3}
console.log(a)
console.log(b)

運行test.js結(jié)果為,

{ name: 1 }
{ name: 1 }
{ name: 2 }
{ name: 2 }
{ name: 2 }
{ name: 3 }

簡單解釋一下上面的代碼:a是一個對象,b是對a對象的引用,此時a和b只想同一塊內(nèi)存,所以前兩個輸出一樣;當(dāng)對b做修改時,則a和b只想同一塊內(nèi)存地址的內(nèi)容發(fā)生了改變,所以a的值改變也體現(xiàn)了出來;當(dāng)b被覆蓋時,b只想了一塊新的內(nèi)存,而a還是只想原來的內(nèi)存,所以最后兩個輸出不一樣。

明白了上面的例子之后,只需要指點3點就能了解exports和module.exports的區(qū)別了,

  1. module.exports初始值為一個空對象{}
  2. exports是只想module.exports的引用
  3. require()返回的是module.exports而不是exports

也就是說,module.exports才是真正的接口,exports只不過是它的一個輔助工具。最攻返回給調(diào)用者的是module.exports而不是exports。

再強調(diào)一點,在node.js中,一個文件對應(yīng)一個模塊。為了方便,模塊中會有一個exports對象,它和module.exports指向同一個變量,所以我們修改exports對象的時候也會修改module.exports對象;當(dāng)我們通過賦值方式為module.exports賦值時候,此時module.exports與exports對象指向的變量就不同了,所以無論exports對象怎么改,都和module.exports對象沒有任何關(guān)系了。

加粗!加粗!加粗!一般來說,推薦使用module.exports,盡量少使用exports。

3. require搜索module的方式

在node.js中模塊有兩種類型,即,

  • 核心模塊
  • 文件模塊

3.1 搜索核心模塊

核心模塊直接使用名稱獲取,例如經(jīng)常使用的http模塊,使用如下代碼獲取,

var http = require('http')
...
http.createServer()

簡要描述一下上面的代碼,node.js中自帶了一個叫做http的模塊,在上述代碼中我們請求它并把返回的值賦值給一個本地變量,這樣本地變量就編程了一個擁有所有http模塊所提供的公共方法的對象。

3.2 搜索文件模塊

在前面創(chuàng)建模塊的demo中,通過require('./hello')語法,如下代碼,

var Hello = require('./hello')
hello = new Hello()
hello.setName('BYVoid')
...
...

這里,我們使用./test來獲取自定義文件模塊,這種通過相對路徑或絕對路徑是文件模塊的搜索方式。

3.3 搜索模塊的規(guī)則

node.js加載模塊時,遵循了如下的加載規(guī)則,

  1. 核心模塊優(yōu)先級最高,直接使用名字加載,再有命名沖突的時候首先加載核心模塊
  2. 文件模塊只能按照路徑加載 -- 相對路徑或絕對路徑,并且可以省略默認(rèn)的.js后綴名
  3. 查找node_modules目錄,當(dāng)我們在調(diào)用npm install <name>命令的時候,會在當(dāng)前目錄下創(chuàng)建node_module目錄來安裝模塊,當(dāng)require遇到一個既不是核心模塊,又不是以路徑形式表示的模塊名稱時,會試圖在當(dāng)前目錄下的node_modules目錄中查找是不是有這樣一個模塊。如果沒有找到,則會在當(dāng)前目錄的上一層的node_modules目錄中繼續(xù)查找,反復(fù)執(zhí)行這一過程,知道遇到根目錄位置。

相對路徑 - 例如: ./hello表示同級目錄,../hello表示上層目錄

絕對路徑 - 例如: /Users/user/Desktop/js/hello

4. 參考鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,733評論 2 41
  • Node.js是目前非?;馃岬募夹g(shù),但是它的誕生經(jīng)歷卻很奇特。 眾所周知,在Netscape設(shè)計出JavaScri...
    Myselfyan閱讀 4,203評論 2 58
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,242評論 0 1
  • 1 Node.js模塊的實現(xiàn) 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對于Node.js的模塊機制大都著...
    zlx_2017閱讀 1,508評論 0 1
  • 于不經(jīng)意間,我們乘著時光的步伐從懵懵懂懂的孩提走向成熟世故的青年。太多的變遷,太多的出世。更在不經(jīng)意間我們丟失了去...
    左鴻鵠閱讀 362評論 0 0

友情鏈接更多精彩內(nèi)容