CommonJS模块与ES6模块及区别

CommonJS模块和ES6模块

        在ES6之前,js本没有模块体系之说,最主要使用的是CommonJS和AMD两种。前者用于服务器,后者用于浏览器,ES6后在语言标准的层面上实现了模块功能,使用简单,称为浏览器和服务器通用的模块解决方案。

CommonJS模块化规范

        Node.js 遵循了 CommonJS 模块化规范,CommonJS 规定了模块的特性和各模块之间如何相互依赖,规定每个模块内部,规定 module 变量代表当前模块,module 变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口,加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。

let { start , exist , readFile } = require('fs');

//也等同于
let fs1 = require('fs');
let start = fs1.start;
let exist = fs1.exist;
let readFile = fs1.readFile;

ES6模块 

        ES6中提供了模块的概念,我们可以向使用模块引用的方式引用模块

import { start, exists, readFile } from 'fs'

首先建一个文件 index.js 定义变量并暴露出去

let num = 10 ;
let obj = {} ;
let arr = [] ;
let func = functiom(){};

export { num , obj , arr , func };
 

然后想要在另一个文件接收这个变量就需要引入 import命令加载这个模块

import { num , obj , arr , func } from 'index.js'
import index from 'index.js'

共同点

 都能够把对象内部的属性进行改变操作

ES6模块与CommonJS模块的差异

CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用

CommonJS模块是运行时加载,ES6模块是编译时输出接口

 CommonJS模块特点:

  1. 对于基本数据类型,属于复制。即会被模块缓存,如果在另外一个模块导入相同的变量也可以对该变量进行赋值
  2. 对于复杂数据类型,是浅拷贝。由于两个模块引用对象指向同一内存空间,因此对该模块的值作出修改时会影响到另一个模块
  3. 当使用require命令加载某一个模块时,就会运行整个模块的代码
  4. 当使用require命令加载同一个模块的时候,不会再执行该模块,而是取到缓存之中的值,CommonJS模块无论加载多少次,都只会在第一次加载的时候运行一次,以后在加载都是在缓存中取值返回第一次运行的结果,除非手动清除系统缓存
  5. 循环加载时,属于加载时执行。即脚本代码在require的时候就会全部执行,一旦出现某个模块被“循环加载”,就只输出已经执行的部分,还未执行的部分不会输出

ES6模块特点 

  1. 静态化,必须定义在顶部,不能使用条件语句,自动采用严格模式
  2. treeshaking(webpack会在打包的时候忽略掉没有用的代码)和编译优化,以及在webpack3中作用域的提升
  3. 外部可以拿到实时的值而不是缓存中的值,是引用而不是拷贝
  4. es6模块中的值是属于动态只读引用
  5. 对于只读来说,就是不能修改引入变量的值,import变量是只读的,无论是基本数据类型还是复杂数据类型,当模块遇到import命令的时候。就会生成一个只读引用。等到脚本真正执行的时候,再根据这个只读引用到被加载的那个模块里面去取值
  6. 对于动态来说,原始值发生变化,import加载的值也发生变化,无论是基本数据类型还是复杂数据类型
  7. 循环加载时,es6模块时动态引用的,只要两个模块之间存在某个引用,代码就能构执行

循环加载 

        循环加载指的是 a.js 也就是a脚本执行依赖于 b.js 也就是b脚本,而b脚本执行又需要a脚本。

 通常,“循环加载”表示存在强耦合,如果处理不当,还可能会导致递归加载,使得程序无法执行,因此应该避免出现。

  • 耦合性(Coupling) ,也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决于模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立性)。耦合性存在于各个领域,而非软件设计中独有的,但是我们只讨论软件工程中的耦合。
  • 递归加载,递归调用之前的语句是从上到下的,函数调用之后的语句是从下到上的,因为后面的语句要等最下层或者最里面最后调用的那个函数执行之后不再调用了再开始执行,然后返回上一层的时候再执行上一层函数调用后面的语句。并且特别注意的是,每次函数返回后直接就是函数调用后面的语句。

CommonJS模块的循环加载 

        CommonJS模块中重要特性就是加载时执行,就是脚本代码在require的时候就会全部执行,如果出现某个模块出现循环加载,就会只输出已经执行了的部分,还没有执行的部分就不会输出。

 ES6模块的循环加载

         ES6处理循环加载和CommonJS有本质上的不同,ES6模块是动态引用,如果使用 import 从一个模块加载变量,那些变量并不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己能够保证真正取值的时候能够取到值。

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值