1. 程式人生 > >node-學習之路02 commonJS模塊

node-學習之路02 commonJS模塊

ext javascrip 證明 des 做了 ava 圖片 一次 再次

1.commonjs 模塊管理

  所有代碼都運行在模塊作用域,不會汙染全局作用域。
  模塊可以多次加載,但是只會在第一次加載時運行一次,然後運行結果就被緩存了,以後再加載,就直接讀取緩存結果。要想讓模塊再次運行,必須清除緩存。
  模塊加載的順序,按照其在代碼中出現的順序。

2.module對象

技術分享圖片技術分享圖片

2.1 module.exports屬性

  module.exports屬性表示當前模塊對外輸出的接口,其他文件加載該模塊,實際上就是讀取module.exports變量。

2.2 exports變量

  為了方便,Node為每個模塊提供一個exports變量,指向module.exports。這等同在每個模塊頭部,有一行這樣的命令:

  

var exports = module.exports;(commonJS隱式做了這個賦值)

2.3 js文件就是一個函數

console.log(arguments)

{ ‘0‘: {},
  ‘1‘: 
   { [Function: require]
     resolve: { [Function: resolve] paths: [Function: paths] },
     main: 
      Module {
        id: ‘.‘,
        exports: {},
        parent: null,
        filename: 
‘C:\\Users\\liang\\Desktop\\node\\hello.js‘, loaded: false, children: [], paths: [Array] }, extensions: { ‘.js‘: [Function], ‘.json‘: [Function], ‘.node‘: [Function] }, cache: { ‘C:\Users\liang\Desktop\node\hello.js‘: [Object] } }, ‘2‘: Module { id: ‘.‘, exports: {}, parent:
null, filename: ‘C:\\Users\\liang\\Desktop\\node\\hello.js‘, loaded: false, children: [], paths: [ ‘C:\\Users\\liang\\Desktop\\node\\node_modules‘, ‘C:\\Users\\liang\\Desktop\\node_modules‘, ‘C:\\Users\\liang\\node_modules‘, ‘C:\\Users\\node_modules‘, ‘C:\\node_modules‘ ] }, ‘3‘: ‘C:\\Users\\liang\\Desktop\\node\\hello.js‘, ‘4‘: ‘C:\\Users\\liang\\Desktop\\node‘ }

console.log(arguments.callee)
[Function]
console.log(arguments.length)
5

  (function (exports, require, module, __filename, __dirname){})()

    exports是module.exports的一個引用

    require引用模塊後,返回給調用者的是module.exports而不是exports

    exports.xxx,相當於在導出對象上掛屬性,該屬性對調用模塊直接可見

    exports =相當於給exports對象重新賦值,調用模塊不能訪問exports對象及其屬性

    如果此模塊是一個類,就應該直接賦值module.exports,這樣調用者就是一個類構造器,可以直接new實例

    這是兩種暴漏的方式,都可以使用

技術分享圖片

下面是引入方式,及結果

    技術分享圖片技術分享圖片

    我們可以看成 exports = module.exports = {} 就是exports 指針指向module.exports的對象

    關於rfequire 引入的返回值是module.exports

    技術分享圖片

 2.4 require 規則

  (1)如果參數字符串以“/”開頭,則表示加載的是一個位於絕對路徑的模塊文件。比如,require(‘/home/marco/foo.js‘)將加載/home/marco/foo.js。

  (2)如果參數字符串以“./”開頭,則表示加載的是一個位於相對路徑(跟當前執行腳本的位置相比)的模塊文件。比如,require(‘./circle‘)將加載當前腳本同一目錄的circle.js。

  (3)如果參數字符串不以“./“或”/“開頭,則表示加載的是一個默認提供的核心模塊(位於Node的系統安裝目錄中),或者一個位於各級node_modules目錄的已安裝模塊(全局安裝或局部安裝)

  (4)如果參數字符串不以“./“或”/“開頭,而且是一個路徑,比如require(‘example-module/path/to/file‘),則將先找到example-module的位置,然後再以它為參數,找到後續路徑。

  (5)如果指定的模塊文件沒有發現,Node會嘗試為文件名添加.js、.json、.node後,再去搜索。.js件會以文本格式的JavaScript腳本文件解析,.json文件會以JSON格式的文本文件解析,.node文件會以編譯後的二進制文件解析。

  (6)如果想得到require命令加載的確切文件名,使用require.resolve()方法。

  2.5模塊緩存

  第一次加載某個模塊時,Node會緩存該模塊。以後再加載該模塊,就直接從緩存取出該模塊的module.exports屬性。

  

require(‘./example.js‘);require(‘./example.js‘).message = "hello";require(‘./example.js‘).message// "hello"

  上面代碼中,連續三次使用require命令,加載同一個模塊。第二次加載的時候,為輸出的對象添加了一個message屬性。但是第三次加載的時候,這個message屬性依然存在,這就證明require命令並沒有重新加載模塊文件,而是輸出了緩存。
  如果想要多次執行某個模塊,可以讓該模塊輸出一個函數,然後每次require這個模塊的時候,重新執行一下輸出的函數。
  所有緩存的模塊保存在require.cache之中,如果想刪除模塊的緩存,可以像下面這樣寫。

  2.6require.main

require.main === module// true

node-學習之路02 commonJS模塊