CommonJS和ES6module的异同

比特幽影
• 阅读 723

开头总结

1 相同点
都是前端模块化的一种
2 不同点

  • 前者利用exports和module.exports导出数据,用require导入;后者利用export和export default导出,利用import导入
  • 前者是动态化加载,可以放在块级作用域中使用;后者是静态加载,在编译的时候就处理了。
  • 前者导出的数据如果是基本数据类型,导出的是拷贝,引用数据类型的话则是引用。后者导出的都是原数据的引用。
  • 前者可以解决循环引用的问题,后者不能解决

    不同点分析

    第一点

    // c.js
    exports.name = "mike";
    module.exports = {
      name: "mike"
    }
    // d.js
    let c = require('./c');
    console.log(c); // { name: 'mike' }

    对于ES6module要在package.json中增加"type": "module"或者采用.mjs扩展名,下面演示代码采用后者

    // b.mjs
    export let a = "hello world";
    const b = "这是b"
    export default b;
    // a.mjs
    import b, {a} from './b.mjs'
    console.log(a); // hello world
    console.log(b); // 这是b
    // 对于export default的变量,引入的时候不需要加{},export的变量需要加{}

    第二点

    CommonJS如下
    只改变d的内容

    // d.js
    function say() {
      let c = require('./c');
      console.log(c);
    }
    say(); // { name: 'mike' }

    ES6module如下
    只改变a.mjs

    function say() {
      import b, {a} from './b.mjs'
      console.log(a);
      console.log(b);
    }
    say(); // 报错

    第三点

    对于CommonJS

    // c.js
    module.exports = "hello world"
    // d.js
    let a = require('./c')
    a = "hi, world"
    console.log(a);
    let b = require('./c')
    console.log(b);
    //hi, world
    // hello world
    
    // 引用数据类型的情况
    // c.js
    exports.name = "hello, world"
    // d.js
    let a = require('./c')
    a.name = "hi, world"
    console.log(a);
    let b = require('./c')
    console.log(b);
    // 
    { name: 'hi, world' }
    { name: 'hi, world' }

    对于ES6module

    // a.mjs
    let a = "hello, world";
    export {a}
    
    // b.mjs
    import {a} from './a.mjs'
    a = "hi, world"
    console.log(a);
    // 报错,Assignment to constant variable.

    因为ES6module导出的是引用,默认导出的是const变量,所以禁止更改其值,修改了则报错.

解决循环引用

1 CommonJS中采用了缓存,对于已经一个模块,require()函数先去缓存中寻找是否已经加载,如果加载了直接从缓存中取;否则先缓存该模块,再去执行,(注意顺序) 有了缓存很好的解决了循环引用的问题。
如下例子存在main.js c.js d.js三个文件, c和d互相引用,main引用c和d

// c.js
let d = require('./d');
console.log("这是c");

// d.js
let c = require('./c')
console.log("这是d");

// main.js
let c = require('./c')
let d = require('./d')
console.log("这是main");
// 结果 
// 这是d
// 这是c
// 这是main
// 而且发现d仅执行了一次,验证了缓存的说法, 当执行到c的第一行的时候,c已经被缓存了,进入d执行第一行的时候,是从缓存中取的c,此时c只是被缓存了还未被执行。

2 ES6module对于循环引用会报错。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
blueju blueju
4年前
关于打的 umd 包在使用时,报 require is not defined 错误的问题出处
首发于<aname"D0c8t"</a背景:前端同事前辈写了一个提供给其他部门的JS插件,写的是提供给前端使用的工具类,使用的是commonjs规范,导出变量使用的是module.exports的方式,使用的是webpack打包,打出的包可正常通过script标签引入使用,但无法通过importxxxfrom"xxx"/
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Easter79 Easter79
3年前
sql注入
反引号是个比较特别的字符,下面记录下怎么利用0x00SQL注入反引号可利用在分隔符及注释作用,不过使用范围只于表名、数据库名、字段名、起别名这些场景,下面具体说下1)表名payload:select\from\users\whereuser\_id1limit0,1;!(https://o
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Peter20 Peter20
4年前
mysql中like用法
like的通配符有两种%(百分号):代表零个、一个或者多个字符。\(下划线):代表一个数字或者字符。1\.name以"李"开头wherenamelike'李%'2\.name中包含"云",“云”可以在任何位置wherenamelike'%云%'3\.第二个和第三个字符是0的值wheresalarylike'\00%'4\
Stella981 Stella981
3年前
JS 中的require 和 import 区别
在研究react和webpack的时候,经常看到在js文件中出现require,还有import,这两个都是为了JS模块化编程使用。CSS的是@import1.ES6模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。Require是CommonJS的语法,CommonJS的模块是对象,输入时
Stella981 Stella981
3年前
PHP导入导出EXCELl,CSV
PHP导入导出Excel,CSVHTML<formaction"{:U('Admin/Unit/importcsv')}"method"post"name"myform"id"myform"enctype"multipart/formdata"<input
Easter79 Easter79
3年前
Springboot+shiro+redis 限制同一账号 同时在多处登录
这里的业务场景,就类似与qq账号不能同时在多部手机登录一样,后者会强制前者下线,被强制下线的用户重新登录又挤掉前者,如此反复.....一.说下我的思路(不供参考)1\.利用Cookie里面的JESSIONID,其实也就是sessionid,是可以获取到的2.利用Deque双向队列,最大maxSize设置为13
Stella981 Stella981
3年前
CommonJs 与 AMD 与 requirejs
CommonJS规范主要解决服务端中library的导入导出问题。NodeJS(同时也包括webpack与npm)是CommonJS规范的实现由于CommonJS规范引入依赖的方式是同步的,而在浏览器端需要进行异步加载,因此创建了AMD规范用于浏览器端管理依赖问题。require.js是AMD规范的一管实现。U