最近在学习使用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); //
console.log(exampleA.addX(1)); //

以上是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); //
mod.incCounter();
console.log(mod.counter); //

上面代码说明,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); //
incCounter();
console.log(counter); //

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

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

ES6中export , export default , import模块系统总结的更多相关文章

  1. JavaScript ES6中,export与export default

    自述: 本来是对new Vue()和export default比较懵的,查了一下,发现我理解错了两者的关系,也没意识到export与export default的区别,先简单的记录一下基本概念,后续 ...

  2. ES6中的export,import ,export default

    ES6模块主要有两个功能:export和importexport用于对外输出本模块(一个文件可以理解为一个模块)变量的接口import用于在一个模块中加载另一个含有export接口的模块.也就是说使用 ...

  3. ES6中的export以及import的使用多样性

    模块功能主要由两个命令构成:export和import.export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能. 一.export导出模块使用部分的几种方式 一个模块就是一 ...

  4. ES6中的export和import

    1.ES6中的模块加载 ES6 模块是编译时加载,编译时就能确定模块的依赖关系,以及输入和输出的变量,相比于CommonJS 和 AMD 模块都只能在运行时确定输入输出变量的加载效率要高. 1.1.严 ...

  5. 解决es6中webstrom不支持import的一个简单方法

    代码如下: export_one.js的代码如下: export function one() { console.log('one'); } export function two() { cons ...

  6. JavaScript ES6中export、import与export default的用法和区别

    前言 相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在看他们之间的区别之前,我们先来看看它们的用法. ES6 import和export的用法 ...

  7. JavaScript ES6中export及export default的区别以及import的用法

    本文原创地址链接:http://blog.csdn.net/zhou_xiao_cheng/article/details/52759632,未经博主允许不得转载. 相信很多人都使用过export.e ...

  8. JavaScript ES6中export及export default的区别

    相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...

  9. ES6中export及export default的区别

    相信很多人都使用过export.export default.import,然而它们到底有什么区别呢? 在JavaScript ES6中,export与export default均可用于导出常量.函 ...

随机推荐

  1. uEditor富文本编辑器

    在配合vue和webpack使用时,在严格模式下注意会报错,需要修改配置. 我采用的方式:----不建议全部取消严格模式,因为一些插件必须要再严格模式才能运行的 对UEditor的严格模式报错文件,取 ...

  2. python自动安装mysql5.7

    python自动安装mysql5.7 python版本:python2.6 centos版本:centos6.9 mysql版本:mysql5.7.19 安装目录路径和数据目录路径都是固定,当然也可以 ...

  3. 鸟哥的linux私房菜学习-(四)linux命令的基本概念

    一.命令格式及使用方式 注意到上面的说明当中,『第一个被输入的数据绝对是命令或者是可运行的文件』! 这个是很重要的概念喔!还有,按下[Enter]键表示要开始运行此一命令的意思. 如下效果一样: 二. ...

  4. Python学习_10__python2到python3

    同样作为动态语言,python的面相对像和ruby有很多类似的地方,这里还是推荐<Ruby元编程>一书来参考学习python的面向对象.然而python并不是纯面向对象设计,所以很多rub ...

  5. Python day 6(3) Python 函数式编程1

    一:函数式编程概念 函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计.函数就是面向过程的 ...

  6. python 模块:xlrd && xlwt

    主要来自:http://www.jb51.net/article/60510.htm python读excel--xlrd 这个过程有几个比较麻烦的问题,比如读取日期.读合并单元格内容.下面先看看基本 ...

  7. angular4.0快速import依赖路径

    快捷键:ALT + ENTER 直接import对应的依赖路径

  8. mysql加锁读

    Locking Reads 在同一个事务中,如果你先查询数据,随后对相关数据进行插入或修改,那么在标准的SLELECT中不会给出足够的保护.在你查询期间另一个事务可以更新或者删除相同的行.InnoDB ...

  9. 自学Aruba1.2-WLAN一些基本常识

    点击返回:自学Aruba之路 自学Aruba1.2-WLAN一些基本常识 1. LAN.WAN.WLAN.WIFI术语 1.1 局域网(Local Area Network,LAN) 是指在某一区域内 ...

  10. 什么是BIG?如何买BIG?

    谈到BIG,就要谈到BIG ONE.BigONE号称"全民交易所",也称"云币国际站".是 INBlockchian(硬币资本)旗下全球区块链资产现货交易所,是 ...