• 技术文章 >web前端 >前端问答

    es6与commonjs有什么区别

    长期闲置长期闲置2022-05-05 18:18:52原创210

    区别:1、CommonJS输出的是一个值的拷贝,ES6输出的是值的引用;2、CommonJS是运行时加载,ES6是编译时输出接口;3、CommonJS的require是同步加载模块,ES6的import是异步加载,有独立模块依赖的解析阶段。

    本教程操作环境:windows10系统、ECMAScript 6.0版、Dell G3电脑。

    es6与commonjs有什么区别

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

    commonjs的用法,我们一起来看一下

    1.首先创建一个lib.js的文件

    // lib.js
    const counter = 3;
    const incCounter = ()=>{
      counter++
    }
    module.exports = {
      counter,
      incCounter
    }

    2.再次创建一个main.js,使用commonjs的方式导入

    // main.js
    var lib = require('./lib');
    console.log(lib)
    console.log(lib.counter);  // 3
    lib.incCounter();
    console.log(lib.counter); // 3

    lib.js模块加载以后,它的内部变化就影响不到输出的lib.counter了。这是因为mod.counter是一个原始类型的值,会被缓存;

    esmodule的用法,我们一起来看一下

    // lib.js
    export let counter = 3;
    export function incCounter () {
      counter++;
    }
    // main.js
    import { counter, incCounter } from './util.mjs'
    console.log(counter);  //3 
    incCounter()
    console.log(counter)  //4

    ES6 模块不会缓存运行结果,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块。

    补充:通过esmodule导入的变量是不能重新赋值修改的。

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

    // CommonJS模块
    let { stat, exists, readFile } = require('fs');
     
    // 等同于
    let _fs = require('fs');
    let stat = _fs.stat;
    let exists = _fs.exists;
    let readfile = _fs.readfile;

    上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。因此commonjs属于再运行时才会加载模块的方式。

    import { stat, exists, readFile } from 'fs';

    上面代码的实质是从fs模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高;

    三、CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段

    同步加载:所谓同步加载就是加载资源或者模块的过程会阻塞后续代码的执行;

    异步加载:不会阻塞后续代码的执行;

    我们来看一个案例,创建如下的目录;

    | -- a.js
    | -- index.js
    | -- c.js
    // a.js
    console.log('a.js文件的执行');
    const importFun = () => {
      console.log(require('./c').c);
    }
    importFun()
    module.exports = {
      importFun
    }
    // index.js
    const A = require('./a');
    console.log('index.js的执行');
    // c.js
    console.log('c.js的运行');
    const c = 3
    module.exports = {
      c
    }

    执行命令 node index.js

    // a.js文件的执行
    // c.js的运行
    // 3
    // index.js的执行

    我们会发现,require的内容会阻塞后续代码的执行。因为c.js先打印出来,然后在是index.js的打印,所以说require()是同步加载的;

    // a.js
    console.log('a.js文件的执行');
    export const importFun = () => {
      import('./c.js').then(({c})=>{
        console.log(c)
      })
    }
    importFun()
    // index.js
    import {importFun} from './a.js'
    console.log('index.js的执行');
    // c.js
    console.log('c.js的运行');
    export const c = 3
    // 结果
    // a.js文件的执行
    // index.js的执行
    // c.js的运行
    // 3

    可以看的出来:import()是异步加载资源的,因为c.js是在index.js的后面打印出来的,并不会阻塞后续代码的执行;

    总结:以上便是commonjs和esmodule的几个区别

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

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

    3: CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段

    【相关推荐:javascript视频教程web前端

    以上就是es6与commonjs有什么区别的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:ES6
    上一篇:es6数组合并方法有哪些 下一篇:es6中有多少种原始数据类型
    千万级数据并发解决方案

    相关文章推荐

    • es6中proxy的用法是什么• es6怎么取数组前几个元素• es6 filter方法的参数有哪些• 什么是es6中的构造函数• es6中find和filter有什么区别
    1/1

    PHP中文网