瀏覽器容許腳本異步加載;下面就是兩種異步加載的語法
// <script src='' defer></script>
// <script src='' async></script>node
defer 與 async的區別
defer 是等到整個頁面正常渲染結束才執行
async 是一旦下載完成,渲染引擎就會中斷渲染,執行這個腳本之後再繼續渲染express
瀏覽器加載ES6模塊時也使用script標籤 可是要加入type='module'(告訴瀏覽器這是一個模塊)
對於帶有type='module'的script瀏覽器都是異步加載的,不會形成瀏覽器堵塞,即等到整個頁面渲染完成再執行模塊腳本
等同於打開了script的defer屬性
// <script src='' type='module'></script> 等同於<script src='' type='module' defer></script>npm
script標籤的async也能夠打開,這時只要加載完成渲染引擎就會中斷渲染當即執行。執行完成再恢復渲染
// <script src='' type='module' async></script> json
ES6 模塊也容許內嵌在網頁中,語法行爲與加載外部腳本徹底一致。
// <script type='module' >
// importr utils from './utils';
// II other code
// </script>
對於外部的模塊腳本 上例是 foo . j s,有幾點須要注意。
• 代碼是在模塊做用域之中運行,而不是在全局做用域中運行。模塊內部的頂層變量是外 部不可見的。
• 模塊腳本自動採用嚴格模式,不管有沒有聲明 use strict。
• 模塊之中可使用 import 命令加載其餘模塊( . j s 後綴不可省略,須要提供絕對 URL 或相對 URL),
也可使用 export 命令輸出對外接口。
• 在模塊之中,頂層的 this 關鍵字返回 undefined,而不是指向 window。也就是說, 在模塊頂層使用
this 關鍵字是無心義的。
• 同一個模塊若是加載屢次,將只執行一次。瀏覽器
---------------------------------------------------
ES6與CommonJS模塊的差別
CommonJS 模塊輸出的是一個值的複製, ES6 模塊輸出的是值的引用。
CommonJS 模塊是運行時加載, ES6 模塊是編譯時輸出接口 。
第二個差別是由於 CommonJS 加載的是一個對象(即 module.exports 屬性
該對象只 有在腳本運行結束時纔會生成。而 ES6 模塊不是對象,它的對外接口只是一種靜態定義
在代 碼靜態解析階段就會生成。
-----------------------------------------------------框架
console.log(module.exports); // module.exports = {}異步
//狀況一
// test.js
var a = 123;
var b = 456;
module.exports.a = a;
module.exports.b = b;async
//index.js
var test = require('./test.js');
console.log(test);//{ a: 123, b: 456 }函數
// 狀況二
// test.js
var a = 123;
var b = 456;
exports.a = a;
exports.b = b;
//index.js
var test = require('./test.js');
console.log(test);//{ a: 123, b: 456 }ui
//方法三
// test.js
var a = 123;
var b = 456;
module.exports.a = a;
exports.b = b;
//index.js
var test = require('./test.js');
console.log(test);//{ a: 123, b: 456 }
// 方法四
// test.js
var a = 123;
var b = 456;
module.exports = a; //這裏交換module.exports和exports的先後順序結果相同 都是123
exports = b;
//index.js
var test = require('./test.js');
console.log(test);//123 //交換module.export和exports的先後順序結果相同
//說明導出的永遠是module.export
module.exports與exports有啥區別
console.log(exports == module.exports);//true
說明exports和module.exports開始指向同一個對象
可是當module.exports = a module.exports地址的指向a了
exports = b exports的指向是b了
總結:導出的永遠是module.exports
想象一下爲啥module.exports和exports,__dirname,__filename能用?
他們是系統變量嗎?
答案是否是
NodeJs的模塊是運行在一個函數當中的
console.log(module); //Module{}對象
console.log(exports); //{}
console.log(__dirname);//I:\back-end\node\NodeLesson
console.log(__filename);//I:\back-end\node\NodeLesson\test.js
就想象有這麼一個函數 你寫的全部代碼可能是運行在這個函數裏面
你所用的module.exports等變量就是這個函數的參數
function xfs(module,require,exports,__dirname,__filename){
console.log(module); //Module{}對象
console.log(exports); //{}
console.log(__dirname);//I:\back-end\node\NodeLesson
console.log(__filename);//I:\back-end\node\NodeLesson\test.js
return module.exports;
}
不用想象了呀,事實就是如此,在node.js中執行下面命令
console.log(arguments);
[Arguments] {
'0': {},
'1':
{ [Function: require]
resolve: { [Function: resolve] paths: [Function: paths] },
main:
Module {
id: '.',
exports: {},
parent: null,
filename: 'I:\\back-end\\node\\NodeLesson\\test.js',
loaded: false,
children: [],
paths: [Array] },
extensions:
[Object: null prototype] { '.js': [Function], '.json': [Function], '.node': [Function] },
cache:
[Object: null prototype] { 'I:\\back-end\\node\\NodeLesson\\test.js': [Module] } },
'2':
Module {
id: '.',
exports: {},
parent: null,
filename: 'I:\\back-end\\node\\NodeLesson\\test.js',
loaded: false,
children: [],
paths:
[ 'I:\\back-end\\node\\NodeLesson\\node_modules',
'I:\\back-end\\node\\node_modules',
'I:\\back-end\\node_modules',
'I:\\node_modules' ] },
'3': 'I:\\back-end\\node\\NodeLesson\\test.js',
'4': 'I:\\back-end\\node\\NodeLesson' }
console.log(arguments[0] === exports);//true
console.log(arguments[1] === require);//true
console.log(arguments[2] === module);//true;
console.log(arguments[3] === __filename);//true
console.log(arguments[4] === __dirname);//true
//而後咱們來看看module.children是什麼
// module.chidren存的是子模塊
//index.js
var test = require('./test.js'); //test.js裏面什麼也不寫
console.log(arguments[2]);
Module {
id: '.',
exports: {},
parent: null,
filename: 'I:\\back-end\\node\\NodeLesson\\index.js',
loaded: false,
children:
[ Module {
id: 'I:\\back-end\\node\\NodeLesson\\test.js',
exports: {},
parent: [Circular],
filename: 'I:\\back-end\\node\\NodeLesson\\test.js',
loaded: true, //這裏的loaded爲true表示子模塊加載完了,也就是執行完
children: [], //require語句纔開始執行console.log(arguments[2]);
paths: [Array] } ],
paths:
[ 'I:\\back-end\\node\\NodeLesson\\node_modules',
'I:\\back-end\\node\\node_modules',
'I:\\back-end\\node_modules',
'I:\\node_modules' ] }
module.loaded表示最外層的函數是否加載完了
module.paths 當我引入的模塊既不是本身的寫的也不是系統自帶的就須要這個paths了
就好比express框架,那就須要npm引入了 npm install express
下載完以後就會出現一個node_modules裏面
Page506 ESLint 的使用