手机版

ES6和CommonJS中模块处理的区别

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:

ES6和CommonJS都有自己的一套措施来处理模块化代码,也就是JS文件之间的相互引用。

为了方便这两种测试方法,使用nodejs环境进行测试

通用的模块化处理

使用require导入其他模块的代码,使用module.exports导出

//export demo . js count=1;module . exports . count=count;module . exports . hello=function(){ var name;this . setname=function(new name){ name=new name;} this . SayHello=function(){ console . log(' hello Mr . ' name);} this . Getid=function(){ return count } }//require demo . jsvar { Hello }=require('。/export demo ')var Hello=new Hello();hello . setname(' Blank ');hello . sayHello();在终端执行node requireDemo.js,返回的结果是‘你好,空白先生’

导出的Hello函数是原函数的副本,修改Hello函数的属性值不会影响其他需要的地方

var { Hello,count }=require('。/export demo ')var Hello=new Hello();//让count添加console . log(hello . getid());console . log(hello . Getid());//发现获取的计数仍然是原来的值console.log(count)//真正的计数其实是改变后的var new Hello=new Hello();console . log(new hello . Getid())var { hello : new hello,count: newCount }=require('。/export demo ')console . log(new count,' new count ');//再次要求,获得的newHello和前面要求的Hello指向同一个副本console.log的模块处理(newhello===hello) es6

在nodejs中运行ES6风格的代码

Nodejs默认不支持ES6的模块处理方案。

但是8.5.0以后,ES6代码的文件格式设置为mjs后,可以使用Node-Experimental-modulesxxx . mjs运行。

//export demo . mjsexport let a=1;//importdemo.mjs从“”导入{a}。/exportdemo.mjs' console.log (a)不同于CommonJS模块处理

CommonJS模块输出一个值的副本(在前一章中验证过),ES6模块输出一个值的引用。

//exportDemo.mjsexport let计数器=1;导出函数InCcounter(){ counter;}//ImportDemo . mjsimport { counter,incCounter } from ' '。/exportdemo . mjs ' inccounter();Console.log(计数器)//打印的结果是2,而不是初始值1。1CommonJS模块是运行时加载,ES6模块是编译时输出接口

Nodejs类的运行环境将在闭包中运行CommonJS模块代码

(函数(exports、require、module、__filename、__dirname) {//Module代码实际存在于此});ES6模块不缓存运行结果,而是动态取加载模块的值,变量始终绑定到它们所属的模块。

//export demo . mjsexport let a=1;导出常量b=2;导出let obj={ };//importdemo.mjs从“”导入{a,b}。/exportdemo.mjs' console.log (a,b)a=1//报告了错误,typeerror :常量变量赋值,导出的值是只读引用obj.x=1/,可以更改属性值。在ES6模块中,我们要多考虑导出Default的语法问题。

有时候我们会在代码中找到export default obj的用法,那么这个default是用来做什么的呢?

Default是一个与ES6引入的export结合使用的关键字,用于设置匿名对象和匿名函数的默认名称

值导出必须有名称,否则将从语法级别报告错误

让我们看一下下面将报告错误的错误示例

导出匿名对象

导出{x: 1 }//报告了一个错误,语法错误:意外标记,这是编译阶段的错误。//正确写入导出默认{ x: 1 }导出匿名函数

导出函数(){}//报告了一个错误,语法错误:意外标记(///正确写入导出默认函数(){}回收加载)

在复杂的模块中,模块之间可能存在相互引用。

commonJS的循环引用操作机制

//a . jsexports。loaded=falsevar b=必需('。/b . js)控制台。日志(' a中的b是JSON。stringify(b))出口。loaded=true控制台。log(' a complete ')//b . jsexports。loaded=falsevar a=必需('。/a . js)控制台。日志(' b中的a是JSON。字符串形式的出口。loaded=true控制台。日志(' b完成')//main。jsvar a=require(' ./a.js')var b=require ' ./b . js)控制台。日志(' main中的a是JSON。stringify(a))控制台。日志(' main中的b是JSON.stringify(b))执行指令nodejs main.js

时序图下的执行步骤分解图如下所示:

ES6的循环引用运行机制

一个会报错的例子

//a.mjsimport { bar } from ' ./b . mjs '控制台。原木(条);导出让foo=' foo from a . mjs '/b . mjsimport { foo } from ' ./a.mjs'console.log(foo)导出让bar=' bar from b . mjs '/main。来自“”的mjsimport { foo } ./a.mjs "从导入{ bar } ./b.mjs'node main.mjs

时序图下的执行步骤分解图如下所示:

ES6的循环引用要特别注意变量是否已被声明,若未被声明的块级作用域变量被其他模块引用时,会报错。

改进方案:循环引用中尽量去出口可以提前确定的值(例如函数),其实我们总是希望去引用模块执行完全后最终确定的变量。

//a.mjsimport { bar } from ' ./b . mjs '控制台。log(bar());export function foo(){ return ' foo from a . mjs ' }//b . mjsimport { foo } from ' ./a . mjs '控制台。log(foo());export function bar(){ return ' bar from b . mjs ' }//main。来自“”的mjsimport { foo } ./a.mjs "从导入{ bar } ./b.mjs'node main.mjs

返回结果:

a.mjsbar中的富(中国姓氏)来自b.mjs

时序图下的执行步骤分解图如下所示:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

版权声明:ES6和CommonJS中模块处理的区别是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。