ES6之module
该博客原文地址:http://www.cnblogs.com/giggle/p/5572118.html
| 一、module概述 |
JavaScript一直没有模块体系,但是伴随着ES6的到来,module随之而来。
ES6module的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入、输出变量。简而言之就是‘编译时加载’。
ES6module相对来说实现得还是比较简单,易上手。
ES6module提倡一个js文件就是一个模块的概念,主要包括两个命令:export和import,用于模块向外提供接口(export)和引入其他模块接口(import)。
好了,下面就说下我说理解的export命令和import命令。
注:学习ES6之module需要有个转换器,因为现在好多还没有支持ES6的module。见“ES6转换ES5”
| 二、export命令 |
export命令说白了就是用于模块对外提供的接口。
语法如下:
var f = 1;
export {f};
或者
export var f = 1;
但是不能是下面这个样子:
var f = 1;
export f;
为什么呢?
需要注意ES6module是向外抛的值的引用,是引用。(这和CommonJS模块不一样,CommonJS是向外抛的值的拷贝)
所以,你像上面这样肯定不对嘛,因为export f就是向外抛的值了,不是引用咯。
并且,还需要注意的是,export不是最后处理的哦,什么意思?
比如test1:
export {name};
var name = 'Monkey';
如上,这样其实向外抛的是空,如果用ES6module的import(import在下面会详情说到)引用它,会输出undefined。
如下(利用import)test2:
import {name} from './test';
console.log(name);
将test1和test2,利用babel转换成ES5后的代码如下:
test1:

test2:

在node环境下运行test2,得下:

所以,export在ES6module中,和代码一样依行执行。而不像ES6module中的import那样会将其提升到模块顶部,首先执行。
| 三、import命令 |
import命令说白了,就是引用export对外提供的接口。对,是引用,而不是赋值。
import的用法如下:
/*
name为test.js文件中export往外抛的引用名,名字必须一一对应
from后面的'./test'为你所引入模块的相对路径
*/
import {name} from './test';
其中,如果你想改变引用名,可以用as,如下:
import {name as ourName} from './test';
如果你想引入模块中的所有变量,可以利用通配符*,然后利用as自定义名称,如下:
//引入test模块的所有抛出的引用,并将其存放在allVar中
import * as allVar from './test';
//随后,如果test模块中有one方法,我们可以这么使用
allVar.one();
像上面这些例子中,我们用import都需要明确指定模块中对应的引用名称,或者使用*全部引用。其实,我们还可以在export中设置default,这样import引用模块时,就不需要指定使用名啦。
什么意思?
如下:
//test模块
function getName(){
console.log('Monkey');
};
//default其实就相当于ES6module为我们设定的一个名字,对应getName的值
export default getName; //使用test模块,one是我随便起的名字,它就对应default,而不需要{}了
import one from './test';
| 四、升华 |
ES6module输出的值是值的引用。我们可以通过一个demo,更透彻地认识这点。
如下:
//模块sample
var i = 0;
export {i};
//模块test1,引入sample模块
import {i} from './sample';
i++;
//模块test2,引入sample模块
import {i} from './sample';
console.log(i);
//模块main,引入test1和test2模块
import './test1';
import './test2';
利用bable转换:

报错了!!在模块test1中的i++是只读的。(’i’ is read-only).
原因就是:由于ES6输入的模块变量,只是一个”符号连接“,所以这个变量是只读的,对它进行重新赋值会报错。(摘自‘阮一峰—ECMAScript6入门’)。
我们再修改下上面的代码,
如下:

利用bable转换如上代码后,利用cmd,运行main.js,得如下结果:

我们在main.js中是利用import引入test1和test2模块,但是,从上面的结果可以看出,他们是引用的同一份sample。
所以,ES6module输出的值是值的引用。且,因为ES6module输出的值是值的引用。所以当出现循环引用模块时,它和CommonJS是不一样的。
如下,CommonJS’s Demo:
注:CommonJS是值的拷贝,不是引用。
main.js
var y = require('./test');
exports.b = 'dorie';
setTimeout(function(){
console.log(y.y);
},2000);
test.js
var b = require('./main');
var y;
setTimeout(function(){
y = 'monkey' + b.b;
},1000);
exports.y = y;
运行main.js,得下结果:

Why?
因为CommonJS是值的拷贝,当执行main.js时,引入test模块,将y的值赋值给main.js里的y变量,此时y是undefined,且已经赋值了,但test模块在1秒后运行setTimeout里的匿名函数后,y变为’monkey’ + b.b,可是对main.js里的y已经无影响,因为是值拷贝嘛。
我们将上述代码换成ES6module的形式,如下:
main.js
import {y} from './test';
export var b = 'dorie';
setTimeout(function(){
console.log(y);
},2000);
test.js
import {b} from './main';
var y;
setTimeout(function(){
y = 'monkey' + b;
},1000);
export {y};
利用Bable将ES6module转换成ES5后,在node环境下运行转换后的main.js,得如下结果:

其实逻辑与上述CommonJS是一样的,但是结果却不一样,原因就是ES6module是值的引用!!
ES6之module的更多相关文章
- 前端模块化小总结—commonJs,AMD,CMD, ES6 的Module
随着前端快速发展,需要使用javascript处理越来越多的事情,不在局限页面的交互,项目的需求越来越多,更多的逻辑需要在前端完成,这时需要一种新的模式 --模块化编程 模块化的理解:模块化是一种处理 ...
- ES6 模块化(Module)export和import详解 export default
ES6 模块化(Module)export和import详解 - CSDN博客 https://blog.csdn.net/pcaxb/article/details/53670097 微信小程序笔记 ...
- 前端MVC Vue2学习总结(七)——ES6与Module模块化、Vue-cli脚手架搭建、开发、发布项目与综合示例
使用vue-cli可以规范项目,提高开发效率,但是使用vue-cli时需要一些ECMAScript6的知识,特别是ES6中的模块管理内容,本章先介绍ES6中的基础与模块化的内容再使用vue-cli开发 ...
- ES6的Module系统
http://es6.ruanyifeng.com/#docs/module Module 的语法 概述 严格模式 export 命令 import 命令 模块的整体加载 export default ...
- 关于ES6的module的循环加载
今天写js时,碰到了一个模块循环加载的错误,下面时例子: // testa.mjs import testb from './testb.mjs'; const {b} = testb; const ...
- ES6的Module 的用法
在vue-cli中遇到的模糊参考 https://www.cnblogs.com/ppJuan/p/7151000.html 解决问题: 在 ES6 之前,社区制定了一些模块加载方案,最主要的有 Co ...
- webpack里CommonJS的require与ES6 的module.exports加载模块有何不同
只需明白commonjs的规则即可,import会被转化为commonjs格式的,babel默认会把ES6的模块转化为commonjs规范的. import vue from 'vue'; //等价于 ...
- commonjs 与 es6相关Module语法的区别
1.export 在接口名字与模块内部的变量之间建立了一一对应的关系,export输出的接口,与其模块内对应的变量值是动态绑定的,即通过暴露的接口可以取到模块内与之对应绑定变量的实时的值. commo ...
- es6 module + webpack
其实在之前本人就看了 es6 里面的一部分内容,当然是阮一峰大神的 ECMAScript 6 入门. 最近闲来无事又来看下,其中 Module 的语法 这章时候,用里面代码跑的时候,理所当然的报错 S ...
随机推荐
- 从RPC开始(一)
这是一篇关于纯C++RPC框架的文章.所以,我们先看看,我们有什么? 1.一个什么都能干的C++.(前提是,你什么都干了) 2.原始的Socket接口,还是C API.还得自己去二次封装... 3.C ...
- scanf()中清除输入缓冲区的几种方法归纳
应用场景:我们使用多个scanf()的时候,如果输入缓冲区还有数据的话,那么scanf()就不会询问用户输入,而是直接就将输入缓冲区的内容拿出来用了,这就导致了前面的错误影响到后面的内容,为了隔离这种 ...
- 用scikit-learn学习DBSCAN聚类
在DBSCAN密度聚类算法中,我们对DBSCAN聚类算法的原理做了总结,本文就对如何用scikit-learn来学习DBSCAN聚类做一个总结,重点讲述参数的意义和需要调参的参数. 1. scikit ...
- OpenGL超级宝典笔记----渲染管线
在OpenGL中任何事物都在3D空间中,但是屏幕和窗口是一个2D像素阵列,所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的 ...
- [C#] C# 知识回顾 - 表达式树 Expression Trees
C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...
- Oracle学习之路-- 案例分析实现行列转换的几种方式
注:本文使用的数据库表为oracle自带scott用户下的emp,dept等表结构. 通过一个例子来说明行列转换: 需求:查询每个部门中各个职位的总工资 按我们最原始的思路可能会这么写: ...
- Response.Redirect引起的性能问题分析
现象: 最近做的一个系统通过单点登录(SSO) 技术验证用户登录.用户在SSO 系统上通过验证后,跳转到该系统的不同模块.而跳转的时间一直维持子啊几分钟左右. 分析步骤: 在问题复现时抓取Hang d ...
- .NET同步与异步之相关背景知识(六)
在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...
- 免费道路 bzoj 3624
免费道路(1s 128MB)roads [输入样例] 5 7 21 3 04 5 13 2 05 3 14 3 01 2 14 2 1 [输出样例] 3 2 04 3 05 3 11 2 1 题解: ...
- 「译」JUnit 5 系列:环境搭建
原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...