node環境與CommonJS規範

1. 環境

首先,咱們來了解一下nodejs執行起來主要須要什麼node

  • CommonJS

commonjs是nodejs所用的模塊規範chrome

  • global對象

咱們知道在瀏覽器中運行的JavaScript包含BOM、DOM,其中window就是一個全局對象,可是nodejs並無BOM、DOM這些東西,全部也沒有window這個全局對象,取而代之的是global,一樣裏面也有一些屬性和方法供咱們使用。json

  • process

表明當前執行的進程,掛在global下面瀏覽器

1.1 CommonJS

  • 每一個文件是一個模塊,有本身的做用域
  • 在模塊內部module變量表明模塊自己
  • module.exports 屬性表明模塊對外的接口

爲了理解以上內容,咱們寫這樣一段代碼緩存

而後在命令行裏運行一下,輸入下面這行代碼進入調試模式(--inspect進入調試模式,-brk在開始的時候停下)bash

接着咱們打開chrome進入 chrome://inspect,回車後能夠看到下面的界面

點擊inspect就能夠進入調試界面了

從圖中咱們能夠看到,咱們實際執行的代碼在nodejs中運行的時候,被一個括號和一個分號包裹住,裏面是一個function,這些都是nodejs內部幫咱們作的(模塊本身的做用域),這個function傳入了5個變量,分別是

  • exports

exports是一個對象,表明模塊的輸出,對外提供看模塊接口,指向module.exports。

注意,不能直接將exports變量指向一個值,由於這樣等於切斷了exports與module.exports的聯繫。函數

下面的寫法是無效的,由於exports再也不指向module.exports了。ui

exports = function(x) {console.log(x)};
複製代碼

下面的寫法hello函數是沒法對外輸出的,由於module.exports被從新賦值了。spa

exports.hello = function() {
  return 'hello';
};
module.exports = 'Hello world';`
複製代碼

這意味着,若是一個模塊的對外接口,就是一個單一的值,不能使用exports輸出,只能使用module.exports輸出。命令行

  • require

require是一個function,表示調用別的模塊時須要調用的function

  • module

module是一個對象,裏面有一個exports屬性。表明模塊自己

  • __filename

文件路徑

  • __dirname

文件所在文件夾路徑

2. require

2.1 require規則

  • /表示絕對路徑,./表示相對於當前文件的
  • 支持js、json、node擴展名,不寫依次嘗試
  • 不寫路徑則認爲是build-in模塊或者各級node_modules內的第三方模塊

2.2 require特性

  • module 被加載的時候執行,加載後緩存

舉個栗子,咱們先寫一個模塊

這個模塊導出一個變量num,並在開始的時候打印一個'hello'

接着,咱們在另外一個文件裏引入這個模塊

運行這個文件

能夠看到,咱們加載了兩次demo模塊,而hello只打印了一次

因此,module只有在第一次被加載的時候會執行

  • 一旦出現某個模塊被循環加載,就只輸出已經執行的部分,還未執行的部分不會輸出

這個定義有點難懂,不過不要緊,咱們仍是經過例子來理解

咱們先寫三個js文件

而後咱們執行main.js文件,執行步驟以下

  1. 首先引入了a.js文件,咱們去加載a.js文件

  2. 在a.js中第一行將x賦值 'a1',接着引入了b.js,咱們又去加載b.js文件

  3. 在b.js中第一行將x賦值 'b1',接着又去引入a.js文件,此時構成循環引用,所以只能引用a.js的部份內容,也就是exports.x='a1',又將x賦值爲'a1',所以首先打印出b.js a1

  4. 接着,a.js打印出來a.js b2,由於b.js的已經執行完畢了,因此引用到的x爲b2

  5. main.js文件中,因爲a.js和b.js都已經執行完畢,因此打印出main.js a2,main.js b2

控制點最終打印

相關文章
相關標籤/搜索