zoukankan      html  css  js  c++  java
  • ES6中export , export default , import模块系统总结

    最近在学习使用Webpack3的时候发现,它已经可以在不使用babel的情况下使用ES6的模块加载功能了。(不包括webpack.config.dev.js文件。

    因为它是是webpack的配置文件,是nodejs直接运行处理的。所以仍需使用CommonJS规范,其他被webpack编译的js模块可以使用es6写法。)

    说到ES6的模块加载功能,我们先复习一下CommonJS规范吧:

    一  . CommonJS规范规定,在每个模块内的module变量代表当前模块。这个变量的module.exports属性是对外开放的接口。

    加载某个模块,其实是加载此模块的module.exports属性。

    exampleA.js
    var x = 5;
    var addX = function (value) {
      return value + x;
    };
    module.exports.x = x;
    module.exports.addX = addX;

    上面代码通过module.exports对外暴露出变量x和函数addX

    每个模块的module对象默认拥有这些属性:

      module.id 模块的识别符,通常是带有绝对路径的模块文件名。

      module.filename 模块的文件名,带有绝对路径。

      module.loaded 返回一个布尔值,表示模块是否已经完成加载。

      module.parent 返回一个对象,表示调用该模块的模块。  

      module.children 返回一个数组,表示该模块要用到的其他模块。

      module.exports 表示模块对外输出的值。

    . export变量:为了方便,每个模块内都有一个指向module.exports的对象 exports。

    .require方法:用于加载模块。

    读取并执行一个JavaScript文件,然后返回该模块的exports对象。

    exampleB.js
    var exampleA = require('./exampleA.js');//加载上文的模块
    
    console.log(exampleA.x); // 5
    console.log(exampleA.addX(1)); // 6

    以上是Commonjs的常用功能。其他功能参考阮大神的:http://javascript.ruanyifeng.com/nodejs/module.html

    ES6中模块规范

    . export方法:

    用法1:

    // profile.js
    export var firstName = 'Michael';
    export var lastName = 'Jackson';
    export var year = 1958;

    用法2:

    // profile.js
    var firstName = 'Michael';
    var lastName = 'Jackson';
    var year = 1958;
    
    export { firstName, lastName, year};
    //export { firstName as obj1, lastName as obj2, year as obj3};//可以使用as关键字重命名

    与CommonJS不同的是:export语句的输出接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

    . import方法

    import {firstName, lastName, year} from './profile.js';
    //import { lastName as surname } from './profile.js';
    //
    import * as profile from './profile.js';

    import命令具有提升效果,会提升到整个模块的头部,首先执行。

    . export default 方法

    // export-default.js
    export default function () {
      console.log('foo');
    }
    //其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。
    // import-default.js
    import customName from './export-default';
    customName(); // 'foo'

    上面的import方法,可以用任意名称指向export-default.js(指向)输出的方法,这时就不需要知道原模块输出的函数名。

    这时import命令后面,不使用大括号。

    如果想在一条import语句中,同时引入default接口和其他接口,可以写成下面这样。

    import _, { each, each as forEach } from 'lodash';

    . import() 方法

    动态加载模块,返回一个 Promise 对象。(nodejs中使用require.ensure实现)

    import('./someModules.js')
      .then(module => {
        console.log(module);
      })
      .catch(err => {
      console.log(err);
    });

    ES6模块与CommonJS模块的区别

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

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

    . 第二个差异是因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,

    它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。(然而nodejs中对ES6模块的实现任是基于自身的CommonJS 并没有实现静态加载)

    CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

    //CommonJS
    //
    lib.js var counter = 3; function incCounter() { counter++; } module.exports = { counter: counter, incCounter: incCounter, };

    上面代码输出内部变量counter和改写这个变量的内部方法incCounter。然后,在main.js里面加载这个模块。

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

    上面代码说明,lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。这是因为mod.counter是对模块内counter对象值的拷贝。

    除非写成一个函数,才能实时获取mod.counter的变动。

    //CommonJS
    //
    lib.js var counter = 3; function incCounter() { counter++; } module.exports = { get: counter() { return counter }, incCounter: incCounter, };

    ES6模块:

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

    结果说明,ES6 模块输入的变量counter是活的(闭包),完全反应其所在模块lib.js内部的变化。

    注:参考阮一峰大神的《ECMAScript6入门》。

  • 相关阅读:
    ES基础(十三)Dynamic Template和Index Template
    ES基础(十一)显式Mapping设置与常见参数介绍
    ES基础(十)Dynamic Mapping 和常见字段类型
    ES基础(九)Query & Simple Query String Query
    ES基础(八)Request Body 与 Query DSL
    Docker 核心技术与实现原理
    error gathering device information while adding custom device
    Linux下使用内核源码单独编译某一模块
    kata container endpoint
    Virtio_user for Container Networking
  • 原文地址:https://www.cnblogs.com/zhuxiaoweb/p/8298140.html
Copyright © 2011-2022 走看看