js發展初期暴露了其缺陷:缺少模塊,後來提出了commonJS規範來規範其模塊的規範。做爲JavaScript新手,發現對於其JavaScript的模塊機制,不是很理解。我查閱了一些資料整理了JavaScript CommonJS的原理和機制。css
這類項目不能使用CommonJS的模塊規範,這是我起初所犯的錯誤。在沒有es6被大多數瀏覽器支持的時候,js文件充斥着var和function,由此引來了命名衝突和污染,使得JavaScript代碼很複雜。es6的class概念出現有效規範了JavaScript的模塊化規範。因爲這類項目只能經過script標籤引入,咱們在這裏講一下script標籤的相關知識。
每當瀏覽器解析到<script>標籤(不管內嵌仍是外鏈)時,瀏覽器會優先下載、解析並執行該標籤中的javaScript代碼,而阻塞了其後全部頁面內容的下載和渲染。根據上述對<script>標籤特性的描述,咱們知道,在該示例中,當瀏覽器解析到<script>標籤時,瀏覽器會中止解析其後的內容,而優先下載腳本文件,並執行其中的代碼,這意味着,其後的test.css樣式文件和<body>標籤都沒法被加載,因爲<body>標籤沒法被加載,那麼頁面天然就沒法渲染了。所以傳統作法是
假定point.js文件:html
//定義類 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } }
則在index.js中引入point.js,這須要在index.html中body的尾部java
<script src="point.js"></script> <script src="index.js"></script>
這樣就能夠在index.js使用point類了。
總結下來:es6
js類庫必須在header中引入,保證對以後script引入的js文件的支持,畢竟script標籤的執行順序是順序執行,script標籤引入順序和實際引入順序相同。後端
自定義的script標籤引入的js文件,要放在body的尾部,保證DOM元素渲染結束。瀏覽器
每一個js文件儘可能是es6 class對象,避免做用域和命名域的衝突。服務器
模塊引用的實例以下:require方法模塊化
const math = require("math");
模塊的定義:
上下文提供了exports對象用於導出當前模塊方法和變量,而且它是惟一的導出出口。在模塊中,還存在一個module對象,他表明模塊自身,exports是module對象的屬性。導出方式:工具
// math.js exports.add = function () { }; module.exports.add = function () { };
ES6模塊不是對象,而是經過export命令顯式指定輸出的代碼,輸入時也採用靜態命令的形式。
因爲ES6模塊是編譯時加載,使得靜態分析成爲可能。有了它,就能進一步拓寬JavaScript的語法,好比引入宏(macro)和類型檢驗(type system)這些只能靠靜態分析實現的功能。 ui
除了靜態加載帶來的各類好處,ES6模塊還有如下好處:
再也不須要UMD模塊格式了,未來服務器和瀏覽器都會支持ES6模塊格式。目前,經過各類工具庫,其實已經作到了這一點。
未來瀏覽器的新API就能用模塊格式提供,再也不必要作成全局變量或者navigator對象的屬性。
再也不須要對象做爲命名空間(好比Math對象),將來這些功能能夠經過模塊提供。
瀏覽器使用ES6模塊的語法以下:
導出對象和變量:
variables.js
var firstName = 'XXX'; var lastName = 'YYY'; export {firstName, lastName};
Point.js
// 導出類對象 export default class Point extends circle { }
引入module
import Point from "Point";
加載機制詳見:es6 module
引用資料:
高靜:js的並行加載與順序執行