浏览器允许脚本异步加载;下面就是两种异步加载的语法 // <script src='' defer></script> // <script src='' async></script> defer 与 async的区别 defer 是等到整个页面正常渲染结束才执行 async 是一旦下载完成,渲染引擎就会中断渲染,执行这个脚本以后再继续渲染 浏览器加载ES6模块时也使用script标签 但是要加入type='module'(告诉浏览器这是一个模块) 对于带有type='module'的script浏览器都是异步加载的,不会造成浏览器堵塞,即等到整个页面渲染完成再执行模块脚本 等同于打开了script的defer属性 // <script src='' type='module'></script> 等同于<script src='' type='module' defer></script> script标签的async也可以打开,这时只要加载完成渲染引擎就会中断渲染立即执行。执行完成再恢复渲染 // <script src='' type='module' async></script> 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; //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 } //方法三 // 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:ack-end odeNodeLesson console.log(__filename);//I:ack-end odeNodeLesson est.js 就想象有这么一个函数 你写的所有代码多是运行在这个函数里面 你所用的module.exports等变量就是这个函数的参数 function xfs(module,require,exports,__dirname,__filename){ console.log(module); //Module{}对象 console.log(exports); //{} console.log(__dirname);//I:ack-end odeNodeLesson console.log(__filename);//I:ack-end odeNodeLesson est.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 的使用