对比ES6和CommonJS

前言

js早期没有模块体系,都是通过script标签引入js代码,当项目越来越大时,会出现一些问题,比如:

  • 变量污染,因为js都是顶层作用域
  • 当js文件相互依赖时,问题会更复杂,引入顺序出错时,会报很多错

为了解决以上问题,就出现了模块化,nodejs使用commonJs模块化规范;es6使用Es Module模块化规范。

CommonJs 用法

导出

可以通过 module.exports进行单个导出,多个导出,或者混合导出

common.js 文件

   // 单个导出
   let a = 1
   module.exports.a = a

   // 多个导出
   let a = 1
   let b = 2
   function add(val1,val2){
     a = val1
     b = val2
     return a+b
   }
   module.exports ={
    a, b, add
   }
   // 混合导出
   
   let a = 1
   let b = 2
   function add(val1,val2){
     a = val1
     b = val2
     return a+b
   }
   module.exports ={
     b, add
   }
   module.exports.a = a

导出也可以直接用exports,省略module

   let a = 1
   exports.a = a

注意

  • 导出不可以直接给 exports赋值,因为本质上导出的是module.exports,当给exports重新赋值对象,exports就会指向新的一块内存空间,它与module.exports的连接就断开了。

具体原因可查看: http://t.zoukankan.com/jianxian-p-12150940.html

// 这样导出的内容会是空对象
    let a = 1
    let b = 2
    exports = {
      a, b
    }

导入

通过require引入

let commons = require('./commons')
console.log(commons) // {a: 1}

动态导入

因为代码发生在运行时,所以可以动态加载代码

    let lists = ["./index.js", "./config.js"]
    lists.forEach((url) => require(url)) // 动态导入

值的改变

通过add方法修改common.js文件中的a,b值,a,b 不会发生变化

let commons = require('./commons')
let result = commons.add(9,0)
console.log('index2===>',result,commons.a, commons.b) // 9 1 2

注意

  • 导入的值是拷贝的,所以可以修改拷贝的值,这会引起变量污染,比如先引入index1.js 再引入index2.js
  • 多次加载同一个js, 只会加载一次
// index1.js
let commons = require('./commons')
commons.a = 11

// index2.js
let commons = require('./commons')
console.log(commons.a) // 11

Es Module 用法

导出

导出分为两种:exportexport default,两者可以同时存在

ESmodule.js 文件

// 导出单个
  export var a = 4
  
// 导出多个
var a = 4
var b = 22
function add(val1,val2){
  a = val1
  b = val2
  return val1+val2
}
export  {
  a, b, add
}
// 或者
export default{
  a, b, add
}

导入

如果是export导出,则用如下方式导入

import {a, b, add}  from './ESmodule'
add(7,7)
console.log('index1====>', a) // index1===> 7

// 或者

import * as all from './ESmodule'
console.log('index1====>', all.a) // index1===> 4

如果是export default导出, 则用如下方式导入

    import esData  from './ESmodule'
    esData.a = '111'
    esData.add(7,7)
    console.log('index1====>', esData.a) // index1===>'111'

如果既有export又有export default导出,则用如下方式导入

// 导出
export var a = 4
var b = 22
function add(val1,val2){
  a = val1
  b = val2
  return val1+val2
}
export default  {
  b  add
}
// 导入
 import esData, {a}  from './ESmodule'
 console.log(a, esData.b) // 4 22

值的改变

当是export导出

  • 导出值是值的引用,并且内部有映射关系,所以在导入文件中,不能直接修改值,否则会报错
  • 但是可以通过导出文件的方法,修改导出文件的变量,这样会导致污染变量
   // 导出文件 ESmodule.js
      var a = 4
      var b = 22
      function add(val1,val2){
        a = val1
        b = val2
        return val1+val2
      }
      export  {
        a, b, add
      }
      
   // 导入文件
   import {a, b, add}  from './ESmodule'
   a = 4// 不可以直接修改,会报错
   add(7,7)
  console.log('index1====>', a) // 通过add方法将ESmodule.js中的a的值改变了,这时输出7

当是export default导出

  • 导出值是浅拷贝,所以可以在导入文件中直接修改值
  • 但是不能修改导出文件的值
  //导出文件 ESmodule.js
     var a = 4
     var b = 22
     function add(val1,val2){
       a = val1
       b = val2
       return val1+val2
     }
     export default{
       a, b, add
     }
     
  // 导入文件
  import esData  from './ESmodule'
  esData.a = 4
  console.log('index1====>', esData.a) // 可以在导入文件中直接修改值 输出4
  add(7,7)
  console.log('index1====>', a) // 通过add方法不能将ESmodule.js中的a的值改 输出4 

exportexport default 的区别

  • 导出次数不同:export可以导出多次, export default只能导出一次
  • 导入方式不同:export在导入时要加{ },export default则不需要,并可以起任意名称
  • 值的改变不同:export只能在导出文件中改变值,export default只能在导入文件中改变值

CommonJs 和 Es Module对比

Es ModuleCommonJs
输出方式export(输出多个)
export default(输出一个)
exports(输出多个)
module.exports(输出一个)
加载可以单独加载某个方法(接口)加载整个模块,即把所有的接口都加载出来
加载时机解析阶段生成接口并对外输出运行阶段加载模块
值的变化输出的是值的引用,
原来模块的值改变,则该加载值也变
输出的值是拷贝的,
已经加载的值,会使用缓冲,
即原来模块的值改变,不会影响已经加载的该值
this指向指向undefned指向该当前模块
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值