1. 程式人生 > >Nodejs學習筆記(三)--- 模組

Nodejs學習筆記(三)--- 模組

目錄

簡介及資料

通過Node.js的官方API可以看到Node.js本身提供了很多核心模組 http://nodejs.org/api/ ,這些核心模組被編譯成二進位制檔案,可以require('模組名')去獲取;核心模組具有最高的載入優先順序(有模組與核心模組同名時會體現)

(本次主要說自定義模組)

Node.js還有一類模組為檔案模組,可以是JavaScript程式碼檔案(.js作為檔案字尾)、也可以是JSON格式文字檔案(.json作為檔案字尾)、還可以是編輯過的C/C++檔案(.node作為檔案字尾);

檔案模組訪問方式通過require('/檔名.字尾')    require('./檔名.字尾')    requrie('../檔名.字尾') 去訪問,檔案字尾可以省略

;以"/"開頭是以絕對路徑去載入,以"./"開頭和以"../"開頭表示以相對路徑載入,而以"./"開頭表示同級目錄下檔案,

前面提到檔案字尾可以省略,Nodejs嘗試載入的優先順序 js檔案 > json檔案 > node檔案

建立一個自定義模組

   以一個計數器為例

var outputVal  = 0;     //輸出值
var increment = 1;    //增量

/* 設定輸出值 */
function seOutputVal (val) {
    outputVal = val;
}

/* 設定增量 */
function setIncrement(incrementVal){
    increment 
= incrementVal; } /* 輸出 */ function printNextCount() { outputVal += increment; console.log(outputVal) ; } function printOutputVal() { console.log(outputVal); } exports.seOutputVal = seOutputVal; exports.setIncrement = setIncrement; module.exports.printNextCount = printNextCount;
自定義模組 示例原始碼

示例中重點在於exports和module.exports;提供了外部訪問的介面,下面呼叫一下看看效果吧

呼叫自定義模組

 

/*
    一個Node.js檔案就是一個模組,這個檔案可能是Javascript程式碼、JSON或者編譯過的C/C++擴充套件。
    重要的兩個物件:
    require是從外部獲取模組
    exports是把模組介面公開    
*/
var counter = require('./1_modules_custom_counter');

console.log('第一次呼叫模組[1_modules_custom_counter]');

counter.seOutputVal(10);               //設定從10開始計數
counter.setIncrement (10);             //設定增量為10

counter.printNextCount();
counter.printNextCount();
counter.printNextCount();
counter.printNextCount();

/*
    require多次呼叫同一模組不會重複載入
*/
var counter = require('./1_modules_custom_counter');

console.log('第二次呼叫模組[1_modules_custom_counter]');
counter.printNextCount();
自定義模式呼叫 原始碼

執行可以發現通過exports和module.exports對外公開的方法都可以訪問!

示例中可以看到,我兩次通過require('./1_modules_custom_counter')獲取模組,但是第二次引用後呼叫printNextCount()方法確從60開始~~~

原因是node.js通過requirerequire多次呼叫同一模組不會重複載入,Node.js會根據檔名快取所有載入過的檔案模組,所以不會重新載入了

注意:通過檔名快取是指實際檔名,並不會因為傳入的路徑形式不一樣而認會是不同的檔案

在我建立的1_modules_custom_counter檔案中有一個printOutputVal()方法,它並沒有通過exports或module.exports提供對外公開訪問方法,

如果1_modules_load檔案中直接訪問執行會出現什麼樣的情況呢?

答案是:TypeError: Object #<Object> has no method 'printOutputVal'

exports和module.exports 區別

    經過上面的例子,通過exports和module.exports對外公開的方法都可以訪問!那既然兩種都能達到效果,但總得有點區別的吧~~~用個例子看看吧!

 

var counter  = 0;     

exports.printNextCount = function (){    
    counter += 2;
    console.log(counter);
}

var isEq = (exports === module.exports);

console.log(isEq);
2_modules_diff_exports.js 檔案原始碼

下面再新建個2_modules_diff_exports_load.js檔案呼叫一下

var Counter = require('./2_modules_diff_exports');

Counter.printNextCount();
2_modules_diff_exports_load.js 檔案原始碼

呼叫後,執行結果如上圖 

我在2_modules_diff_exports_load.js檔案中輸出了isEq的值  ( var isEq = (exports === module.exports); ),返回的true 

PS:注意是三個等號,如果不清楚自已查查資料吧!

不用急著下結論,把這兩個JS檔案分別改成module.exports對應的程式碼

//修改後的2_modules_diff_exports.js原始碼如下
var counter  = 0;     

module.exports = function(){    
    counter += 10;
    this.printNextCount = function()
    {
        console.log(counter);    
    }
}

var isEq = (exports === module.exports);

console.log(isEq);
//修改後的2_modules_diff_exports_load.js檔案原始碼如下
var Counter = require('./2_modules_diff_exports');

var counterObj = new Counter();
counterObj.printNextCount();

呼叫後,執行結果如上圖 

我在2_modules_diff_exports_load.js檔案中輸出了isEq的值  ( var isEq = (exports === module.exports); ),返回的false,這與用先前得到的結果不一致!

PS:不要用Counter.printNextCount();去訪問,你只會得到一個錯誤的提示

API提供瞭解釋

http://nodejs.org/api/modules.html

Note that exports is a reference to module.exports making it suitable for augmentation only. If you are exporting a single item such as a constructor you will want to use module.exports directly instead
exports僅僅是module.exports的一個地址引用。nodejs只會匯出module.exports的指向,如果exports指向變了,那就僅僅是exports不在指向module.exports,於是不會再被匯出

參考其它理解:

http://www.hacksparrow.com/node-js-exports-vs-module-exports.html

http://zihua.li/2012/03/use-module-exports-or-exports-in-node/

module.exports才是真正的介面,exports只不過是它的一個輔助工具。 最終返回給呼叫的是module.exports而不是exports。
所有的exports收集到的屬性和方法,都賦值給了Module.exports。當然,這有個前提,就是module.exports本身不具備任何屬性和方法。
如果,module.exports已經具備一些屬性和方法,那麼exports收集來的資訊將被忽略。

exports和module.exports 覆蓋

 上面也也基本明白了exports和module.exports的關係和區別,但如果同時針對printNextCount()方法存在exports和module.exports,結果如何?

呼叫結果

從結果可以看出,並沒有報錯,表示可以這麼定義,但最終module.exports覆蓋了exports

雖然結果不會報錯,如果這麼用開發中難免會有一些問題存在,所以

1.最好別分別定義module.exports和exports

2.NodeJs開發者建議匯出物件用module.exports,匯出多個方法和變數用exports

其它...

   API中還提供了其它的方法,就不細講了,在上面例子的基礎上自已動手一輸出就知道了

  module.id

  返回string型別的模組標識,一般為完全解析後的檔名


  module.filename

返回一個string型別的完全解析後文件名


  module.loaded

返回一個bool型別,表示是否載入完成


  module.parent

返回引用該模組的模組


  module.children

  返回該模組引用的所有模組物件的陣列

相關推薦

Nodejs學習筆記--- 模組

目錄 簡介及資料 通過Node.js的官方API可以看到Node.js本身提供了很多核心模組 http://nodejs.org/api/ ,這些核心模組被編譯成二進位制檔案,可以require('模組名')去獲取;核心模組具有最高的載入優先順序(有模組與核心模組同名時會體現) (本次主要說

Nodejs學習筆記--- 事件模組

目錄 簡介及資料 events是node.js 最重要的模組,events模組只提供了一個物件events.EventEmitter,EventEmitter 的核心是事件發射與事件監聽器。 Node.js中大部分的模組,都繼承自Event模組。 與DOM樹上事件不同,不存在事件冒

JAVA學習筆記

byte repl efi ber 時間 clas 區分大小寫 增強for size @SuppressWarnings("resource")是用來壓制資源泄露警告的。比如使用io類,最後沒有關閉。Set集合特點:1)無序,不隨機2)元素唯一3)沒下標註意:Collect

thinkphp5.0學習筆記獲取信息,變量,綁定參數

名稱 自動識別 參數順序 query images 報錯 oca nds arc 1.構造函數: 控制器類必須繼承了\think\Controller類,才能使用: 方法_initialize 代碼: <?php namespace app\lian\control

最優化學習筆記最速下降法

tex track enter water pos 最優 content 分享 clas 最優化學習筆記(三)最速下降法

【轉】Nodejs學習筆記--- 簡介及安裝Node.js開發環境

ack 目錄 javascrip 難度 時間 網站開發 clas jetbrains 常用 目錄 學習資料 簡介 安裝Node.js npm簡介 開發工具 Sublime Node.js開發環境配置 擴展:安裝多版本管理器 學習資料   1.深入淺出Node.j

python學習筆記

list 內存 寫入 odin move 列表 付出 open ada 文件的操作一般分三步: 1、打開文件,獲取文件的指針(句柄) 2、通過指針(句柄)操作文件 3、關閉文件 現在有以下文件: 我們為愛還在學 學溝通的語言

Redis學習筆記常用命令整理

mes ember nbsp end 插入 學習筆記 頻道 hash value Redis 常用命令 1.DEL key 刪除key2.EXISTS key 檢查key是否存在3.KEYS * 查看所有的key4.EXPIRE key seconds 設置key的過期時

nodejs爬蟲筆記

target ole n+2 如何獲取 利用 mod git brush 所有 思路:通過筆記(二)中代理的設置,已經可以對YouTube的信息進行爬取了,這幾天想著爬取網站下的視頻信息。通過分析YouTube,可以從訂閱號入手,先選擇幾個訂閱號,然後爬取訂閱號裏面的視頻分

Django 學習筆記模板導入

文件 文件中 訪問 from lang sts class rom 網頁 本章內容是將一個html網頁放進模板中,並運行服務器將其展現出來。 平臺:windows平臺下Liunx子系統 目前的目錄: hello ├── manage.py ├── hello │ ├─

Git學習筆記遠程庫GitHub協同開發,fork和忽略特殊文件

tex 情況 learn 多人 版本管理 獲得 logs 秘鑰 多個 遠程庫   遠程庫,通俗的講就是不再本地的git倉庫!他的工作方式和我們本地的一樣,但是要使用他就需要先建立連接!   遠程庫有兩種,一個是自己搭建的git服務器;另一種就是使用GitHub,這個網站就是

jQuery學習筆記

對象 idt 命名空間 goto div hid 右鍵 func 切換 jQuery中的事件和動畫 jquery中的事件 加載DOM 兩者等價但有細微區別 $(document).ready(function(){//編寫代碼}) 在DOM完全就緒時就可以被調用。

《EFFECTIVEC++》學習筆記

ict lsp alq list dict baidu vsr .com 學習筆記 REDIS%E6%BA%90%E7%A0%81%E5%89%96%E6%9E%90-DICT%E9%81%8D%E5%8E%86%E7%AE%97%E6%B3%95 http://mp3.

學習筆記——數據庫命令的應用

cal 名稱 nbsp ges bsp tex 密碼 連接字符串 集合 學習筆記(三)——數據庫命令的應用 一、存儲過程 (一)基本概念 存儲過程就是固化SQL數據庫系統內部的SQL語句,這樣做的好處是可以提高執行效率,提高數據庫的安全性,減

Hibernate學習筆記 --- 映射枚舉類型

enume rto 希望 enum 類名 賦值 rom cart org 對於枚舉類型,不能通過org.hibernate.annotations.Type註解來簡單的映射對應的數據庫字段類型(除非自定義類型)。對此,Hibernate提供了javax.persis

C#可擴展編程之MEF學習筆記:導出類的方法和屬性

學習 說了 如何 mod ati dem ont num imp 前面說完了導入和導出的幾種方法,如果大家細心的話會註意到前面我們導出的都是類,那麽方法和屬性能不能導出呢???答案是肯定的,下面就來說下MEF是如何導出方法和屬性的。   還是前面的代碼,第二篇中已經提供了下

【轉載】.NET Remoting學習筆記信道

star fig cati 服務端 pro net string spa 處理類型 目錄 .NET Remoting學習筆記(一)概念 .NET Remoting學習筆記(二)激活方式 .NET Remoting學習筆記(三)信道 參考:♂風車車.Net .NET Fra

Nodejs學習筆記-----Buffer

pretty 成員 保存 n) tin 設置 amp 個數 普通 Node.js Buffer(緩沖區) JavaScript 語言自身只有字符串數據類型,沒有二進制數據類型。 但在處理像TCP流或文件流時,必須使用到二進制數據。因此在 Node.js中,定義了一個 Buf

python3學習筆記多線程與多進程

ttr pid make start lee close gif 自己 oops 線程thread,庫threading 進程process,庫Process 使用起來方法跟其他語言相似,也不需要下載其他的庫,語言自帶的庫裏就有 1.多線程的例子 1 #coding=

Nodejs學習筆記----- 模塊系統和函數

參數 spa 而且 split response 另一個 簡約 也有 方法 Node.js模塊系統------->有開發基礎很好理解 為了讓Node.js的文件可以相互調用,Node.js提供了一個簡單的模塊系統。 模塊是Node.js 應用程序的基本組成部分,文件和