分享

模塊化

  • seajs --CMD(就近依賴,只有用到纔會導出,瀏覽器端)
  • requirejs --AMD(前置依賴,瀏覽器端)
  • commonJS --node(服務器端)

commonjs

node自帶模塊化功能,一個js文件就是一個模塊,模塊this不是global,實現基礎是閉包。

模塊引用時會找到絕對路徑
模塊加載過會有緩存,把文件名作爲key,module作爲value
node實現模塊化就是增加了一個閉包,並且自執行這個閉包
模塊加載時是同步操作
默認會加後綴js,json,node
不同模塊下的變量不會相互衝突
//全局對象,在任意的地方都可以使用,不經過任何聲明就可以使用
 //瀏覽器(在瀏覽器裏面,全局對象global是一個概念,其具體的反映就是window)
 console.log(this === window)   //true
 
 //node(在node裏面,全局對象global具像化了,真正指代全局對象)
	//1. 文件裏
 console.log(this)    //{}  
 	//2. 命令行裏
 console.log(global) // ...
 	// => node文件中的this不是global
 

閉包

//node
console.log(this)
var a = 1
console.log(this.a) //undifined
a = 1
console.log(global.a) //在這個文件環境裏面找不到a就會向上找到全局global, a=1
//類似於
var a = 1
function(){
	a = 1
	console.log(global.a)
}
//模塊對應的閉包函數的參數
console.log(arguments)

導出文件的具體實現

//exports內存中指向的就是module.exports指向的那塊空間
//require一個方法
//Module模塊類
//__filename該文件絕對路徑
//__dirname該文件父文件夾的絕對路徑
(function(exports,require,Module,__filename,__dirname){
  module.exports = exports = this = {}
  //文件中的所有代碼
  

  //不能改變exports指向,因爲返回的是module.exports,所以是個{}
  return module.exports
})

所以我們require的時候其實就相當於執行了這麼一個閉包,然後返回的就是我們的module.exports。

require是怎麼樣的?

  • 每個模塊都會帶一個require方法
  • 動態加載(v8執行到這一步纔會去加載此模塊)
  • 不同模塊的類別,有不同的加載方式,一般有三種常用後綴
    – 後綴名爲.js的JavaScript腳本文件,需要先讀入內存再運行
    – 後綴名爲.json的JSON文件,fs 讀入內存 轉化成JSON對象
    – 後綴名爲.node的經過編譯後的二進制C/C++擴展模塊文件,可以
  • 查找第三方模塊
    – 如果require函數只指定名稱則視爲從node_modules下面加載文件,這樣的話你可以移動模塊而不需要修改引用的模塊路徑。
    第三方模塊的查詢路徑包括module.paths和全局目錄。

關於閉包

js權威指南

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}

var foo = checkscope();
foo();

作用域鏈
f = { Scope: [AO, checkscope, global] }

就是因爲這個作用域鏈,f 函數依然可以讀取到 checkscope.AO 的值,說明當 f 函數引用了 checkscope.AO 中的值的時候,即使 checkscope被銷燬了,但是 JavaScript 依然會讓checkscope.AO 活在內存中,f 函數依然可以通過 f 函數的作用域鏈找到它,正是因爲 JavaScript 做到了這一點,從而實現了閉包這個概念。

即使創建它的上下文已經銷燬,它仍然存在(比如,內部函數從父函數中返回)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章