es6 Module
前言:
这是阮一峰老师的ECMA6入门module一章的缩减,只抽取了我在项目中有用到的内容。带着问题去看老师的教程。感觉吸收更快,也明白了偶尔遇到的export不出来的问题。
es6模块设计思想:
ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
es6模块不是对象:
// CommonJS模块
let { stat, exists, readFile } = require('fs'); // 等同于
let _fs = require('fs');
let stat = _fs.stat, exists = _fs.exists, readfile = _fs.readfile;
上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取3个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。
ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。不会加载整个fs。
// ES6模块
import { stat, exists, readFile } from 'fs';
由于 ES6 模块是编译时加载,使得静态分析成为可能。
除了静态加载带来的各种好处,ES6 模块还有以下好处。
- 不再需要
UMD模块格式了,将来服务器和浏览器都会支持 ES6 模块格式。目前,通过各种工具库,其实已经做到了这一点。 - 将来浏览器的新 API 就能用模块格式提供,不再必须做成全局变量或者
navigator对象的属性。 - 不再需要对象作为命名空间(比如
Math对象),未来这些功能可以通过模块提供。
关于es6模块的特性
一、严格模式:
es6模块默认使用严格模式,不管你有没有使用 'use strict'
二、export
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
需要特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一 一对应关系。
这里的意思是不能直接输入一个变量,函数,类
// 报错
export ; // 报错
var m = ;
export m;
正确的,有一一对应关系的export,函数 function,类 class 也是要遵守这种规则的。
// 写法一:这种我不理解
export var m = ; // 写法二:输出一个对象,这个对象有一个 m 属性,m属性与m变量,一一对应
var m = ;
export {m}; // 写法三:输出一个n,n与m一一对应
var n = ;
export {n as m};
// 报错:输出的 f 就是 函数 f 没有对应关系
function f() {}
export f; // 正确
export function f() {}; // 正确
function f() {}
export {f};
export的换名输出
function v1() { ... }
function v2() { ... }
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion
};
三、import
使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。
注意:import在编译阶段执行,可以理解为跟变量提升,函数提升有一样的特性,但是比这两种提升晚一点执行。
foo();
import { foo } from 'my_module';
上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。
import语句会执行所加载的模块,因此可以有下面的写法。只执行一下lodash,但是不输入任何值
import 'lodash';
只想列出不同的import写法:
// 变量名与export一一对应
import {firstName, lastName, year} from './profile'; // 使用新变量名代替
import { lastName as surname } from './profile';
四、模块的整体加载
一个模块中可以有多个export,import中可以使用 * 把他们全部收在一个对象中 * as mymodule
import * as circle from './circle';
五、export default 命令
为模块设置默认输出,在import的时候不需要使用{},也可以随便给一个名字这个默认输出。
// export-default.js
export default function foo() {
console.log('foo');
} // 或者写成
function foo() {
console.log('foo');
}
export default foo; // import
import xxx from 'export-default.js'
本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。
// modules.js
function add(x, y) {
return x * y;
}
export {add as default};
// 等同于
// export default add; // app.js
import { default as xxx } from 'modules';
// 等同于
// import xxx from 'modules';
正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。(怪不得老是说,找不到模块)
// 正确
export var a = ; // 正确
var a = ;
export default a; // 错误
export default var a = ;
同时想要两种输出
import _, { each } from 'lodash';
八、es6模块加载的实质
ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝(值类型是拷贝,引用类型是引用),而ES6模块输出的是值的引用(值类型,引用类型都是引用)。
问题1:
commonJS 得到的是一个复制,require后得到的mod.counter,跟lib.js里面的counter已经没有联系,(可以理解为require多少次,复制多少份)
// lib.js
var counter = ;
function incCounter() {
counter++;
}
module.exports = {
counter: counter,
incCounter: incCounter,
}; // main.js
var mod = require('./lib'); console.log(mod.counter); //
mod.incCounter();
console.log(mod.counter); //
es6模块的优点就是共享一份,因为它输出的仅仅是引用
// lib.js
export let counter = ;
export function incCounter() {
counter++;
} // main.js
import { counter, incCounter } from './lib';
console.log(counter); //
incCounter();
console.log(counter); //
es6 Module的更多相关文章
- JavaScript ES6 module 模块
在使用JavaScript开发大型项目时,模块开发概念是一个必须考虑的问题.其目的就是通过命名空间对各类业务对象进行一定的封装,防止命名冲突. 本篇着重介绍ES6 module中的export和imp ...
- 在 npm 中使用 ES6 module
node 从 v8.5.0起 支持了 ES6 module. 只需保存文件名为 .mjs ,并通过一个option 可以开启执行,如 node --experimental-modules index ...
- 深入 CommonJs 与 ES6 Module
目前主流的模块规范 UMD CommonJs es6 module umd 模块(通用模块) (function (global, factory) { typeof exports === 'obj ...
- 再次梳理AMD、CMD、CommonJS、ES6 Module的区别
AMD AMD一开始是CommonJS规范中的一个草案,全称是Asynchronous Module Definition,即异步模块加载机制.后来由该草案的作者以RequireJS实现了AMD规范, ...
- 通过ES6 Module看import和require区别
前言 说到import和require,大家平时开发中一定不少见,尤其是需要前端工程化的项目现在都已经离不开node了,在node环境下这两者都是大量存在的,大体上来说他们都是为了实现JS代码的模块化 ...
- 前端模块化IIFE,commonjs,AMD,UMD,ES6 Module规范超详细讲解
目录 为什么前端需要模块化 什么是模块 是什么IIFE 举个栗子 模块化标准 Commonjs 特征 IIFE中的例子用commonjs实现 AMD和RequireJS 如何定义一个模块 如何在入口文 ...
- CommonJS与ES6 Module的使用与区别
CommonJS与ES6 Module的使用与区别 1. CommonJS 1.1 导出 1.2 导入 2. ES6 Module 2.1 导出 2.2 导入 3. CommonJS 与 ES6 Mo ...
- es6 module + webpack
其实在之前本人就看了 es6 里面的一部分内容,当然是阮一峰大神的 ECMAScript 6 入门. 最近闲来无事又来看下,其中 Module 的语法 这章时候,用里面代码跑的时候,理所当然的报错 S ...
- es6+require混合开发,兼容es6 module,import,export
近一年,一直很忙,做了不少的项目,不过都不是太满意,毕竟是别人的作品,不好意思写出来.最近打算开发一个es6的项目,项目中用到require,本文主要讲解es6的module规范怎么与require的 ...
随机推荐
- Java程序员应该知道的10个Eclipse调试技巧
Eclipse是众多Java程序员实用的开发工具,其中开发技巧也是繁多,但作为优秀的Java程序员,需要掌握最起码的调试技巧. 1 条件断点 2 异常断点 3 监视点 4 评估/检查 5 修改变量值 ...
- 使用sqlldr向Oracle导入大的文本(txt)文件
我们有多种方法可以向Oracle数据库里导入文本文件,但如果导入的文本文件过大,例如5G,10G的文本文件,有些方法就不尽如意了,例如PLSQL Developer中的导入文本功能,如果文本文件过大, ...
- 怎样以学习单片机为契机,逐步成为优秀的project师
现状 不知道阅读本文的读者,在初学单片机时是否和我以前一样迷茫.看到各种新的术语,疑惑不解:不知道从何学起:照着书中的样例一步一步做都没有问题,可是自己试着做东西,遇到各种问题却不会解决,向别人提问, ...
- ASP.NET MVC进阶
ASP.NET MVC进阶 一.ASP.NET MVC中的AJAX应用 首先,在ASP.NET MVC中使用自带的ajax功能,必须要导入2个js文件(顺序不能颠倒): ASP.NET MVC提供了2 ...
- mysql支持的数据类型及其测试
原文:mysql支持的数据类型及其测试 1.基础知识 1.1如何来查看mysql的帮助手册 ?int Help float; 1.2创建表的规则 CREATE TABLE [IF NOT EXISTS ...
- c#多线程随记回顾
C#多线程随记回顾 1.创建多线程方式知道的有三种: ---手动创建Thread.使用线程池.使用task任务 ---手动创建Thread,分两种带参数和不带参数的帮助委托器 eg: //帮助器委托 ...
- Redis简介与简单安装
Redis简介与简单安装 一.NoSQL的风生水起 1.1 后Web2.0时代的发展要求 随着互联网Web2.0网站的兴起,传统的关系数据库在应付Web2.0网站,特别是超大规模和高并发的SNS类 ...
- JavaScript实例技巧精选(9)—计算器实例1
>>点击这里下载完整html源码<< 这是截图: 利用Javascript和html实现的一个计算器实例,核心代码如下: <script language="J ...
- Fiddler工具
Fiddler初探 我们知道监视Http和Https请求的工具有多种,例如:HttpWatch,FireBug等.但是今天接触到一种新的工具Fiddler.Fiddler能记录所有客户端和服务器的ht ...
- 从uibutton的点击谈谈ios的响应事件
最近在做一个项目,接连遇到两个关于点击事件的问题. 1.点击button不能响应事件的. 2.子view的frame超出了父view的容器大小,也不能响应点击事件. 效果图如右: 1.第一张图中的弹出 ...