一、概述

之前提到的几种模块化规范:CommonJS、AMD、CMD都是社区提出的。ES 2015在语言层面上实现了模块功能,且实现简单,可以替代CommonJS和AMD规范,成为在服务器和浏览器通用的解决方案

二、特性

1、ES Module自动启用严格模式

 <script type="module">
console.log(this); //undefined
</script>

2、ES Module运行在单独的作用域中,与外界互不干扰

    <script type="module">
var foo = 100;
console.log(foo);//100
</script>
<script type="module">
console.log(foo);//Uncaught ReferenceError: foo is not defined
</script>

3、ES Module是通过CORS方式请求外部文件,需外部文件支持CORS请求

 //该文件支持CORS请求,则可以请求成功
<script type="module" src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script> //该文件不支持CORS请求,报跨域错误
<script type="module" src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

4、ES Module引用的文件会延迟执行

//index.js
alert('hello');
//index.html
<body>
<script type="module" src="./index.js"></script> 等价于 <script defer src="./index.js"></script>
<p>
文本内容
</p>
</body>

执行结果【js的加载并未影响到DOM的加载】

三、export命令

由于在ES Module中,每个模块都是一个单独的作用域,如果想使模块内的变量暴露出去,使用export关键字,导入其他模块的关键字使用import

1、挨个导出变量

//module.js
export var name = "张三"; export function add(a, b) {
return a + b;
} export var obj = {
name: 'jack'
};

2、批量导出变量

//module.js
var name = "张三"; function add(a, b) {
return a + b;
} var obj = {
name: 'jack'
}; export { name, add, obj }

优点:在脚本尾部,使用一个export统一导出,清晰简洁

3、导出默认数据

//module.js
export default 'es module'
或者
export default function(a,b){
return a+b;
}

注意:说完import后再说注意事项

4、导出时起别名,使用as关键字

//module.js
var name = "张三"; function add(a, b) {
return a + b;
} var obj = {
name: 'jack'
}; export { name as v1, add as v2, obj as v3}

四、import命令

要想接受其他模块通过export导出的成员时,使用import关键字

1、import导入其他模块中的变量

//module.js
var name = "张三"; function add(a, b) {
return a + b;
} export { name ,add }
//app.js
import { name, add as MathAdd} from "./module.js"
console.log(name);//张三
console.log(MathAdd(1, 1)) //2

注意:

1.1使用相对路径 后缀名和./不能省略

​ import {name} from "./module.js"

1.2使用绝对路径

​ import {name} from "/demo/module.js"

1.3使用全路径

​ import {name} from "http://localhost:8080/demo/module.js"

1.4可以在导入模块时使用as 起别名

​ 起别名后,as前的变量不可使用了

2、使用import只执行引入文件,不提取引入文件中的成员时

  1. import {} from "./module.js";
  2. import './module.js'【常用】
//module.js
console.log('module.js中执行') var name = "张三"; function add(a, b) {
return a + b;
} var obj = {
name: 'jack'
}; export { name, add, obj }
//app.js
import {} from "./module.js";
或者写成
import './module.js'
//index.html
<body>
<script type="module" src="./app.js"></script>
//执行结果
//module.js中执行
</body>

当多次执行同一个import语句时,只会执行一次

3、模块的整体加载

使用import除了可以加载单个值,也可以一次性加载模块导出的所有值

//module.js

var name = "张三";

function add(a, b) {
return a + b;
} var obj = {
name: 'jack'
}; export { name, add, obj }
//app.js
import * as all './module.js'
console.log('name:',all.name);
console.log('obj',all.obj);
console.log(add(1,1))

五、export default

前面使用export导出模块内的成员时,需要指定具体的成员名称,同样加载时需要根据导出的具体名称进行加载。还有一种快捷的导出方式,使用export default 为模块指定默认导出,每个模块只能使用一次export default

1、导出匿名成员时,使用任意变量接受成员

//module.js
export default function(a, b) {
return a + b;
}
 //app.js
import add from "./module.js";
console.log(add(1,2));

因为使用export导出成员时是匿名的,所以在导入时并不知道这个成员的名字是什么,这时候就可以随意写变量去接受这个匿名成员,案例中使用add接受的匿名函数,也可以使用其他名称接收。

注意:export default也可以导出具名成员,但效果和导出匿名成员是一样的

//module.js
export default function add(a, b) {
return a + b;
}
//或者
function add(a,b){
return a + b;
}
export default add
 //app.js
import temp from "./module.js";
console.log(temp(1,2));

总结:使用export default导出成员,在外部加载时都视为匿名成员加载,可以随意起变量名接受

2、同时导入其他模块的默认成员和具名成员时

//module.js
var name = 'jack';
var age = 19;
export { name, age } //导出默认成员
export default 'default export'
//app.js
import str,{name,age} from "./module.js";
或者
import {name,age,default as str} from "./module.js"
console.log(str);//default export
console.log(name);//jack
console.log(age);//19

3、另类的默认导出

//module.js
var number = 1;
export { number as default }
等同于
export default number;
//app.js
import { default as number} from "./module.js"
console.log(number); //1

总结:可见export default的本质就是导出一个名字叫default的成员,当导出的成员叫default时,接受这个成员可以随意命名

4、使用export default来导出类

//Person.js
export default class Person(){
....
} //main.js
import Person from "./Person.js";
const person = new Person();

5、比较一下默认输出和正常输出

//1.默认输出
export default function add(a,b){
return a + b;
}
//接受默认输出
import temp from './module.js' //2.具名输出
function add (a,b){
return a + b;
}
export {add}
//接受具名输出
import {add} from './module.js'

总结:使用默认导出时,在外部接受成员,不需要使用大括号;使用具名输出时,在外部接受成员时,import后需要使用大括号

六、迷惑性的点

1、export批量导出变量时,导出的并不是对象字面量

//module.js
var name = 'jack';
var age = 19;
export { name, age }
//export {name,age} 并不是导出的一个对象,而是export批量导出的语法

2、import加载多个变量时,并不是ES6的解构用法

import {name,age} from "./module.js"
//impot后面的大括号并不是解构作用

3、import导入的变量都是常量,不可修改,与CommonJS不同

七、export和import的复合用法

当我们在文件内import一个成员后,同时把它导出时

//index.js
import {Button} from './button.js'
export { Button } 可以写成 export {Button} from "./button.js"

八、import()函数

import关键字导入其他模块成员时,必须写在最顶层作用域,不可嵌套在其他逻辑处理中。如果说我们想在某段逻辑执行完成后去动态加载某些成员,这时候可以使用import()函数加载

//module.js
var name = "张三"; function add(a, b) {
return a + b;
} var obj = {
name: 'jack'
}; export { name, add, obj }
export default function() {
return '匿名成员'
}
//app.js
//使用setTimeout来模拟一个异步加载的过程
setTimeout(() => {
//import返回的是个promise,返回的模块内容都在回调函数的参数中(moduleResult)
import ("./module.js").then(moduleResult => {
console.log(moduleResult)
console.log(moduleResult.add)
console.log(moduleResult.name)
console.log(moduleResult.default)
console.log(moduleResult.obj)
}) //也可以直接把成员结构出来
import ("./module.js").then(({add,name,obj,default:defaultData}}) => {
console.log(moduleResult.add)
console.log(moduleResult.name)
console.log(moduleResult.defaultData)
console.log(moduleResult.obj)
})
}, 2000);

前端模块化之ES Module的更多相关文章

  1. JS JavaScript模块化(ES Module/CommonJS/AMD/CMD)

    前言 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了, jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得 ...

  2. JS 模块化- 05 ES Module & 4 大规范总结

    1 ES Module 规范 ES Module 是目前使用较多的模块化规范,在 Vue.React 中大量使用,大家应该非常熟悉.TypeScript 中的模块化与 ES 类似. 1.1 导出模块 ...

  3. 前端模块化——彻底搞懂AMD、CMD、ESM和CommonJS

    我们知道,在NodeJS之前,由于没有过于复杂的开发场景,前端是不存在模块化的,后端才有模块化.NodeJS诞生之后,它使用CommonJS的模块化规范.从此,js模块化开始快速发展. 模块化的开发方 ...

  4. 前端模块化工具-webpack

    详解前端模块化工具-webpack webpack是一个module bundler,抛开博大精深的汉字问题,我们暂且管他叫'模块管理工具'.随着js能做的事情越来越多,浏览器.服务器,js似乎无处不 ...

  5. 前端模块化开发之seaJs

    了解后端语言的童鞋一定听过模块化开发的概念,比如java.python等后端语言都有自己的模块化特性,然而和后端语言相比,javascript还尚未实现模块化的功能,虽然之后的更高版本可能引入模块化开 ...

  6. 前端模块化:RequireJS

    前言 前端模块化能解决什么问题? 模块的版本管理 提高可维护性 -- 通过模块化,可以让每个文件职责单一,非常有利于代码的维护 按需加载 -- 提高显示效率 更好的依赖处理 -- 传统的开发模式,如果 ...

  7. 前端模块化开发学习之gulp&browserify篇

     随着web应用的发展,前端的比重占得越来越多,编写代码从而也越来越复杂.而通常我们需要将不同功能或者不同模块的代码分开写,最后在html中一起加载,这样做是可以的,但是当你需要进行维护或者是二次开发 ...

  8. 基于fis的前端模块化和工程化方案

    前端构建工具 面对日益复杂的前端环境以及前端技术.node技术的高速发展,前端的开发也越来越工程化,体系化,也就是出现了前端自动化构建工具.他们完成的任务目标基本是: js,css,图片的自动压缩合并 ...

  9. 【webpack学习笔记(一)】流行的前端模块化工具webpack初探

    从开发文件到生产文件   有一天我突然意识到一个问题,在使用react框架搭建应用时,我使用到了sass/less,JSX模版以及ES6的语法在编辑器下进行开发,使用这些写法是可以提高开发的效率.可是 ...

随机推荐

  1. kubernets之pod的标签拓展

    一 标签的拓展使用 1.1 标签的作用范围不仅仅适用于pod对node以及其他类的大部分资源同样适用 k label node node01 gpu=true k是kubectl的别名形式 同样对于n ...

  2. 构造无字母数字Webshell

    异或: 补充: A的ascii为65,对应二进制是01000001 <?php echo "1"^"A"; ?> 将"A"和&q ...

  3. IE浏览器直接在页面中显示7z文件而不是下载问题解决

    IE浏览器中输入7z文件的完整下载URL后,不是保存文件,而是直接在页面中显示(当然是乱码) 这是因为浏览器对不同的资源文件处理的方式不同,例如图片文件,一般会直接打开,所以我们可以不用7z,使用zi ...

  4. 主题模型值LDA

    主题模型(topic model)是以非监督学习的方式对文集的隐含语义结构(latent semantic structure)进行聚类(clustering)的统计模型. 主题模型主要被用于自然语言 ...

  5. 部署自动初始化Schema的数据库

    我们使用容器的方式部署数据库组件,特别是企业有大量的项目开发业务的,部署的开发.测试数据库组件较多时.经常会遇到以下问题: 业务需要使用数据库,但部署完数据库后,需要在数据库中执行创建schema的操 ...

  6. 安装OpenDaylight及Openflow插件

    1. 安装 Java 和 Maven CentOS7: yum install java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64 ma ...

  7. 前端面试之JavaScript中数组的方法!【残缺版!!】

    前端面试之JavaScript中数组常用的方法 7 join Array.join()方法将数组中所有元素都转化为字符串并连接在-起,返回最后生成的字 符串.可以指定一个可选的字符串在生成的字符串中来 ...

  8. ETL调优的一些分享(上)(转载)

    ETL是构建数据仓库的重要一环.通过该过程用户将所需数据提取出来,并按照已定义的模型导入数据仓库.由于ETL是建立数据仓库的必经过程,它的效率将影响整个数据仓库的构建,因此它的有效调优具有很高的重要性 ...

  9. 为什么要内存对齐?Go 语言有时也需要考虑对齐的问题

    https://mp.weixin.qq.com/s/NE6Y2TVxrl-cpY-36puQcQ

  10. Linux下编译安装源码包软件 configure ,make, make install, make test/check, make clean 假目标

    http://www.360doc7.net/wxarticlenew/541275971.html 一.程序的组成部分 Linux下程序大都是由以下几部分组成: 二进制文件:也就是可以运行的程序文件 ...