ES6的模块化设计思想是静态化,也就是说,在编译的时候确定模块的依赖关系,以及输出输出入的变量。而CommonJSAMD模块都是在运行时确定的。ES6的模块不是对象,而是通过export显示指定输出的代码,再通过import命令输入。

  1. // 模块输入
  2. import { start,address } from 'util'

上面的模块输入加载了两个方法,即使util模块内有其它方法也不会加载,只会加载上面引入的两个方法,这种加载称为“编译时加载”或静态加载

需要注意的是,ES6的模块自动采取严格模式,不管头部有没有加上"use strict"都会开启严格模式。严格模式的限制如下:

1、变量必须先声明再使用

2、函数参数不能有同名属性,否则报错

3、不能使用with语句

4、不能对只读属性赋值,否则报错

5、不能使用前缀0表示八进制数,否则报错

6、不能删除不可删除的属性,否则报错

7、不能删除变量delete prop,会报错,只能删除属性delete global[prop]

8、eval不会在它的外层作用域引入变量

9、evalarguments不能被重新赋值

10、arguments不会自动反映函数参数的变化

11、不能使用arguments.callee

12、不能使用arguments.caller

13、禁止this指向全局对象

14、不能使用fn.callerfn.arguments获取函数调用的堆栈

15、增加了保留字(比如protectedstaticinterface


export和import命令

模块主要有exportimport构成,export规定模块对外的接口,import用于输入模块提供的功能。

模块导出

  1. // util模块
  2. // 类型
  3. function type(a){
  4. return typeof a
  5. }
  6. // 计算
  7. function sum(a,b) {
  8. return a * b
  9. }
  10. // 判断是否为数组
  11. function isArray(a) {
  12. return a instanceof Array
  13. }
  14. export { type,sum } // 按需导出

模块导入

  1. import { type,sum } from './util'
  2. let num = sum(10,5)
  3. console.log(num) // 50

上面两种方式是可选的方式导出的,也就是说,import导入模块的时候,只会加载export导出的方法,其它的方法不会被import加载,并且import引入util模块可以按需引入,引入自己需要的模块即可,其它未引入的模块也不会加载,这也就是静态加载的好处。

除了export { xxx,xxx }的按需导出外,ES6还提供了export default的默认导出,默认导出的方法,在import导入的时候,不需要跟导出名一直,可以自定义名称接收导出的方法。

  1. // util模块
  2. // 计算
  3. function sum(a,b) {
  4. return a * b
  5. }
  6. // 判断是否为数组
  7. function isArray(a) {
  8. return a instanceof Array
  9. }
  10. export default sum // 默认导出
  1. import aaa from './util' // 导入时名字可以自定义
  2. let num = aaa(10,5)
  3. console.log(num) // 50

其实这个default就是一个叫做default的变量,这个变量可以被任意命名,在import导入的时候,取任何名称都可以匹配上default导出的方法。

按需和默认导出

export { xxx,xxx }export default默认导出可以同时使用

  1. // util模块
  2. function type(a){
  3. return typeof a
  4. }
  5. function sum(a,b) {
  6. return a * b
  7. }
  8. function isArray(a) {
  9. return a instanceof Array
  10. }
  11. export { type,sum }
  12. export default isArray
  1. // 导入
  2. import { type,sum }from './util'
  3. import aaa from './util'

模块的整体加载

上面的导出方法都是加载模块内对应的方法,模块的整体加载要使用*,也就是加载全部,语法如下

  1. import * as util from './util';
  2. // 在页面中使用
  3. let num = util.sum(10,5)
  4. console.log(num) // 50

这种写法是将模块整体加载,用*指定一个对象,所有输出的值都加载在这个对象上面。通过该对象.方法名来获取对应方法。

需要注意的是,ES6的模块是静态分析的,不允许对模块进行改变,所以下面写法是不允许的:

  1. util.sum = 'hello' // 报错
  2. util.sum = function () {} // 报错

模块继承

模块之间也是可以继承的,假设A模块继承了B模块

  1. // A模块
  2. function sum(a,b) {
  3. return a * b
  4. }
  5. function isArray(a) {
  6. return a instanceof Array
  7. }
  8. export * from 'B' // 输出B模块的所有属性和方法,忽略模块内的default方法
  9. export { sum }
  10. export default isArray

export * 命令会忽略B模块的default方法,因为A模块内部有自己的default方法。


模块的重命名

  1. // util模块
  2. export { sum as s }
  3. // 页面
  4. import { s } from './util' // 引入命名后的方法

模块按需引入import()

正常情况下import是需要在页面顶层引入的,并且import的引入执行的优先级是最高的,例如:

  1. let s = sum(10,5)
  2. import { sum } from './util'

上面这种写法是允许的,程序会执行import的引入,然后再执行let s = sum(10,5),但这种写法会默认导入模块,并且是在顶层导入。

es6提供了动态导入功能:import(),当程序执行到该语句的时候才会导入,并且是同步执行,import()返回的是一个Promise,所以可以使用then方法和async-await

Promise写法

  1. import('./util.js')
  2. .then(el=>{
  3. console.log(el.t(100)); // number
  4. console.log(el.sum(10,5)); // 50
  5. })

async-await写法

  1. async function getImport(){
  2. let { sum } = await import('./util.js')
  3. console.log(sum(2,8));
  4. }
  5. getImport() // 16

也可以通过解构的方式获取

  1. import('../module/import.js')
  2. .then(({sum})=>{
  3. console.log(sum(20,5)); // 100
  4. })

如果模块是default默认导出,其实default就是一个键名

  1. import('../module/import.js')
  2. .then((e)=>{
  3. console.log(e.default([1,2,3])); // true
  4. })

default也可以通过具名的形式导入(取别名)

  1. import('../module/import.js')
  2. .then(({default : isA})=>{
  3. console.log(isA([1,2,3])); // true
  4. })

import.meta

在使用一个模块时,有时候需要知道该模块本身的信息(比如模块的路径),import命令新增了一个元属性import.meta,可以返回当前模块的信息。

注意import.meta只能在模块内使用,在模块外使用会报错

  1. // util模块
  2. function sum(a,b) {
  3. return a * b
  4. }
  5. function getMeta(){
  6. return import.meta // 获取当前模块的元信息
  7. }
  8. export { sum,getMeta }
  1. // console.log(import.meta); // import.meta只能在模块内使用,在模块外部使用会报错
  2. import('./util.js')
  3. .then(el=>{
  4. console.log(el.getMeta()); // {url: 'http://127.0.0.1:5500/module/import.js', resolve: ƒ}
  5. })


案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果觉得这篇文章对你有帮助,欢迎点亮一下star哟

Module理解及使用的更多相关文章

  1. 对drupal的理解【转】

    写本文是想跟刚用drupal的朋友,分享一下心得,国内用drupal的太少了,希望大家能好好交流. 希望几分钟看完后你能马上上手drupal,至少能理解hook,api,theme,module,cc ...

  2. 图像处理&计算机视觉中upscale,downscale的翻译理解

    最近在看SAN网络(Second-order Attention Network for Single Image Super-Resolution)的论文,其中的Upscale module理解的不 ...

  3. angular.module 详解

    AngularJS 模块 模块包含了主要的应用代码. 一个应用可以包含多个模块,每一个模块都包含了定义具体功能的代码. 可以将module理解成一个容器,可以往其中放入controllers.serv ...

  4. Android Studio使用教程(一)(转)

    今年的Google全球开发者大会虽然没有新的Android系统和设备,但是还是推出了一些不错的产品,Android Studio就是其中之一.这个基于Intellij IDEA开发的Android I ...

  5. Android Studio初步使用教程

    今年的Google全球开发者大会虽然没有新的Android系统和设备,但是还是推出了一些不错的产品,Android Studio就是其中之一.这个基于Intellij IDEA开发的Android I ...

  6. Android Studio使用教程图文详解

    谷歌表示Android Studio 1.0 能让开发者“更快更有生产力”,并认为它可以代替 Eclipse,同时为Eclipse 用户提供迁移步骤.代码自动提示.运行响应速度.都比Eclipse来的 ...

  7. Android Studio使用教程(一)

    今年的Google全球开发者大会虽然没有新的Android系统和设备,但是还是推出了一些不错的产品,Android Studio就是其中之一.这个基于Intellij IDEA开发的Android I ...

  8. 第二章 andrid studio创建项目

    原文 http://blog.csdn.net/zhanghefu/article/details/9326735 第二章 andrid studio创建项目 第二章 andrid studio创建项 ...

  9. [Android Studio] Android Studio使用教程(一)

    转载:http://blog.csdn.net/hyr83960944/article/details/37509113 今年的Google全球开发者 大会虽然没有新的Android系统和设备,但是还 ...

  10. (七)理解angular中的module和injector,即依赖注入

    (七)理解angular中的module和injector,即依赖注入 时间:2014-10-10 01:16:54      阅读:63060      评论:1      收藏:0      [点 ...

随机推荐

  1. vs2019中使用Git,新建项目时总提示部分项目位于解决方案文件夹外

    最终还是用Git工具传上去的. 小伙子,用Git Bush或者Git CMD 和Git GUI传吧 我是用Git GUI. Git GUI汉化.感谢大佬 https://blog.csdn.net/u ...

  2. kubernetes笔记-2-基本操作

    一.kubectl的基本操作 语法:   kubectl [command] [type] [name] [flags] 语法说明:   command:对资源执行相应操作的子命令,如:get.cre ...

  3. .NET 7 的 AOT 到底能不能扛反编译?

    一:背景 1.讲故事 在B站,公众号上发了一篇 AOT 的文章后,没想到反响还是挺大的,都称赞这个东西能抗反编译,可以让破解难度极大提高,可能有很多朋友对逆向不了解,以为用 ILSpy,Reflect ...

  4. 说一下 ArrayDeque 和 LinkedList 的区别?

    大家好,我是小彭. 在上一篇文章里,我们聊到了基于链表的 Queue 和 Stack 实现 -- LinkedList.那么 Java 中有没有基于数组的 Queue 和 Stack 实现呢?今天我们 ...

  5. Velocity模板引擎的的使用示例(入门级)

    简单说下这个引擎的两个分支(虽然语言不同调用方法大同小异): 1.Java平台下的:org.apache.velocity 2..Net平台下的:NVelocity 注:本文章不涉及到后端只说模板的使 ...

  6. Oracle12c异常关闭后启动PDBORCL(ORA-01033)

    这个问题已经困扰了我好几天找解决方案,终于找到: 由于Oracle12c的特殊性,但许多用户并不想在创建用户时前面要加"C##" 那么就要创建PDBORCL数据库,来与Oracle ...

  7. log4j漏洞原理

    一.前置知识 1.JNDI接口 JNDI即Java Naming and Directory Interface(JAVA命名和目录接口),它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发 ...

  8. 大规模爬取(新浪为例子)网页之downloader、parser的封装(涉及编码等细节)

    import requests import cchardet import traceback from lxml import etree def downloader(url,timeout = ...

  9. 安装es可视化软件Kibana

    一 Kibana介绍 Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作. 您.可以使用 Kibana 对 Ela ...

  10. vue 单独封装分页组件

    一.在components文件夹下新建 pagination.vue <template> <div class="page-wrap"> <ul&g ...