什么是模块

模块是自动运行在严格模式下并且没有办法退出运行的 JavaScript 代码。

在模块顶部创建的变量不会自动被添加到全局变量作用域,这个变量仅在模块的顶级作用域中存在,而且模块必须导出一些外部代码可以访问的元素。

模块也可以从其他模块导入绑定。

在模块的顶部,this 的值是 undefined。

模块不支持 HTML 风格的代码注释。

导出的基本语法

用 export 关键字将一部分已发布的代码暴露给其它模块。

// 导出数据
export var color = "red";
export let name = "JiaJia";
export const magicNumber = 7 // 导出函数
export function sum(num1, num2) {
return num1 + num2;
} // 导出类
export class Rectangle {
constructor(length, width) {
this.length = length;
this.width = width;
}
} // this is private function
function subtract(num1, num2) {
return num1 - num2;
} // define a function
function multiply(num1, num2) {
return num1 * num2;
} // export it
export multiply;

导入的基本语法

通过 import 关键字导入在另一个模块中导出的功能。

import { identifier1, identifier2 } from "./example.js"

import 后面的大括号表示从给定模块导入的绑定(binding),关键字 from 表示从哪个模块导入给定的绑定。

当从模块中导入一个绑定时,它就好像使用 const 定义的一样。结果是你无法定义另一个同名变量(包括导入另一个同名绑定),也无法在 import 语句前使用标识符或改变绑定的值。

导入单个绑定

import { sum } from "./example.js";

console.log(sum(1, 2)); // 3

// 抛出错误
sum = 1;

导入多个绑定

import { sum, multiply, magicNumber } from "./example.js"

console.log(sum(1, magicNumber)); // 8
console.log(multiply(1, 2)); // 2

导入整个模块

// 命名空间导入
import * as example from "./example.js"; console.log(example.sum(1, example.magicNumber)); // 8
console.log(example.multiply(1, 2)); // 2

不管在 import 语句中把一个模块导入了多少次,该模块只执行一次。

如果同一个应用程序中的其他模块也从 example.js 导入绑定,那么这些模块与此代码将使用相同的模块实例。

导入绑定的一个微妙怪异之处

export var name = "JiaJia";
export function setName(newName) {
name = newName;
}
import { name, setName } from "./example.js";

console.log(name); // "JiaJia"
setName("L");
console.log(name); // "L" name = "JiaJia"; // 抛出错误

导出和导入时重命名

function sum(num1, num2) {
return num1 + num2;
} export {
sum as add
};
import { add as sum } from "./example.js";

模块的默认值

模块的默认值指的是通过 default 关键字指定的单个变量、函数或类,只能为每个模块设置一个默认的导出值。

export default function (num1, num2) {
return num1 + num2;
}

等同于

function sum (num1, num2) {
return num1 + num2;
} export default sum;

等同于

function sum (num1, num2) {
return num1 + num2;
} export { sum as default };

导入默认值

import sum from "./example.js";

console.log(sum(1, 2)); // 3

导入默认值和以外的值:

import sum, { color } from "./example.js";

或者

import { default as sum, color } from "./example.js";

重新导出一个绑定

import { sum } from "./example.js";
export { sum }

或者简写成如下形式:

export { sum } from "./example.js";

导出时也可以定义别名

export { sum as add } from "./example.js";

导出一切:

export * from "./example.js";

无绑定导入

// 没有 export 或 import 的模块代码
Array.prototype.pushAll = function(items) {
if (!Array.isArray(items)) {
throw new TypeError("参数必须是一个数组");
} return this.push(...items);
}
import "./example.js"

加载模块

在Web浏览器中使用模块

  • <script>元素中通过src属性指定一个加载代码的地址来加载 JavaScript 代码文件
  • 将 JavaScript 代码内嵌到没有 src 属性的<script>元素中
  • 通过 Web Worker 或 Service Worker 的方法加载并执行 JavaScript 代码文件

<Script>中使用模块

<!-- 加载一个 JavaScript 模块文件 -->
<script type="model" src="module.js"></script> <!-- 内联引入一个模块 -->
<script type="model">
import { sum } from "./example.js";
let result = sum(1, 2);
</script>

Web浏览器中的模块加载顺序

模块按照它们出现在 HTML 文件中的顺序执行,也就是说,无论模块中包含的是内联代码还是指定 src 属性,第一个 <script type="module"> 总是在第二个之前执行。

Web浏览器中的异步模块加载

当应用 async 属性时,脚本文件将在文件完全下载并解析后执行。

脚本在文档中的顺序不会影响脚本执行的顺序。

<!-- 无法保证这两个哪个先执行 -->
<script type="module" async src="module1.js"></script>
<script type="module" async src="module2.js"></script>

将模块作为 Worker 加载

Worker,例如 Web Worker 和 Service Worker,可以在网页上下文之外执行 JavaScript 代码。

// 默认按照脚本的方式加载 script.js
let worker = new Worker("script.js");
// 默认按照模块的方式加载 script.js
let worker = new Worker("script.js", { type: "module" });

浏览器模块说明符解析

浏览器要求模块说明符具有以下几种格式之一:

  • 以/开头的解析为从根目录开始
  • 以./开头的解析为从当前目录开始
  • 以../开头的解析为从父目录开始
  • 以URL格式
// 从 https://www.example.com/modules/example1.js 导入
import { first } from "./example1.js"; // 从 https://www.example.com/example2.js 导入
import { second } from "../example2.js"; // 从 https://www.example.com/example3.js 导入
import { third } from "./example3.js"; // 从 https://www.example.com/example4.js 导入
import { fourth } from "https://www.example.com/example4.js";

【读书笔记】【深入理解ES6】#13-用模块封装代码的更多相关文章

  1. python解析xml模块封装代码

    在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...

  2. 《Linux内核设计与实现》读书笔记(十七)- 设备与模块

    本章主要讨论与linux的设备驱动和设备管理的相关的4个内核成分,设备类型,模块,内核对象,sysfs. 主要内容: 设备类型 内核模块 内核对象 sysfs 总结 1. 设备类型 linux中主要由 ...

  3. 20150206读书笔记<深入理解计算机系统>

    ●第一章 C是系统级编程的首选.C++显示支持抽象,属于应用级程序设计语言. 简单例子: 一个典型系统的硬件组成: 存储器的层次结构: 注:存储器层次结构的设计思想是,该层存储器作为下一层存储器的高速 ...

  4. 深入理解ES6之《用模块封装代码》

    什么是模块 模块是自动运行在严格模式下并且没有办法退出运行的Javascript代码 在模块的顶部this的值是undefined 其模块不支持html风格的代码注释除非用default关键字,否则不 ...

  5. 使用ECMAScript 6 模块封装代码

    JavaScript 用"共享一切"的方法加载代码,这是该语言中最容易出错且最容易让人感到困惑的地方.其他语言使用诸如包这样的概念来定义代码作用域,但在 ECMAScript 6 ...

  6. 读书笔记-你不知道的JS上-闭包与模块

    闭包定义 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行. 看一段最简单的闭包代码: function foo() { var a = 2; //闭包 fun ...

  7. 《C++ Primer Plus》读书笔记之五—函数-C++的编程模块

    函数-C++的编程模块   1.C++对于返回值的类型有一定的限制:不能是数组,但可以是其他任何类型——整数.浮点数.指针,甚至可以是结构和对象(有趣的是,虽然C++函数不能直接返回数组,但可以将数组 ...

  8. AngularJS in Action读书笔记4(实战篇)——创建Statistic模块

    个人感觉<Angularjs in action>这本书写的很好,很流畅,循序渐进,深入浅出,关键是结合了一个托管于Github上的实例讲解的,有代码可查,对于初学者应该是个不错的途径.( ...

  9. 《Linux内核设计与实现》读书笔记 第十七章 设备与模块

    一.设备类型 1. Unix系统 - 块设备 - 字符设备 - 网络设备 2. 块设备 通常缩写为blkdev,它是可寻址的,寻址以块为单位,块大小随设备不同而不同:块设备通常支持重定位操作,也就是对 ...

随机推荐

  1. pthread线程属性介绍

    线程属性 创建线程函数 int pthread_create (pthread_t* restrictthread,  const pthread_attr_t* restrictattr,void* ...

  2. Configuring WS-Security UsernameToken and WS-SecureConversation (Symmetric Connection Creation)

    Context This procedure provides a detailed process of all necessary steps to secure Web Services wit ...

  3. 自学Zabbix3.10.1.5-事件通知Notifications upon events-媒介类型自定义脚本

    自学Zabbix3.10.1.5-事件通知Notifications upon events-媒介类型自定义脚本

  4. Github-karpathy/char-rnn代码详解

    Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan  2016-1-10 ...

  5. IDEA快速创建Maven+SpringBoot项目时:Cannot download https://start.spring.io;Status:403

    先展示一下我遇到的问题: 用浏览器搜索是有页面的,但是但是但是呢,用IDEA快速构建的时候就报403 咳咳!巴格虐我万千遍,我待技术如初恋... 我看到的解决办法有以下两种,当然,我只想说:" ...

  6. Mac 终端——常用命令语

    mac系统如何显示和隐藏文件 苹果Mac OS X操作系统下,隐藏文件是否显示有很多种设置方法,最简单的要算在Mac终端输入命令.显示/隐藏Mac隐藏文件命令如下(注意其中的空格并且区分大小写): 显 ...

  7. AVL树的单双旋转操作

    把必须重新平衡的节点称为å.对于二叉树,å的两棵子树的高度最多相差2,这种不平衡可能有四种情况: 对å的左儿子的左子树进行插入节点(左-左) 对å的左儿子的右子树进行插入节点(左-右) 对å的右儿子的 ...

  8. SSL/TLS通信

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/31 复习基本概念 对称密码:加密和解密使用同一密匙. 公钥密码: ...

  9. ArcGIS API for JavaScript 4.2学习笔记[28] 可视域分析【使用Geoprocessor类】

    想知道可视域分析是什么,就得知道可视域是什么 我们站在某个地方,原地不动转一圈能看到的所有事物就叫可视域.当然平地就没什么所谓的可视域. 如果在山区呢?可视范围就会被山体挡住了.这个分析对军事上有十分 ...

  10. linux系统日常管理复习题讲解

    1. 如何看当前Linux系统有几颗物理CPU和每颗CPU的核数? 2. 查看系统负载有两个常用的命令,是哪两个?这三个数值表示什么含义呢? 3. vmstat r, b, si, so, bi, b ...