ECMAScript 2015 规范在 JavaScript 语言中引入了 module,也有了 import 和 export 语句。在本文中,我们一起来学习 JavaScript 模块,以及怎样用 import和export来组织代码。
![]() 在互联网的洪荒时代,网站主要用 HTML和 CSS 开发的。如果将 JavaScript 加载到页面中,通常是以小片段的形式提供效果和交互,一般会把所有的 JavaScript 代码全都写在一个文件中,并加载到一个 但是后来 JavaScript 在浏览器中发挥着重要的作用,迫切需要使用第三方代码来完成常见任务,并且需要把代码分解为模块化的文件,避免污染全局命名空间。 ECMAScript 2015 规范在 JavaScript 语言中引入了 module,也有了 import 和 export 语句。在本文中,我们一起来学习 JavaScript 模块,以及怎样用 模块化编程在 JavaScript 中出现模块的概念之前,当我们想要把自己的代码组织为多个块时,一般会创建多个文件,并且将它们链接为单独的脚本。下面先举例说明,首先创建一个
index.html <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>JavaScript Modules</title>
</head>
<body>
<h1>Answers</h1>
<h2><strong id="x"></strong> and <strong id="y"></strong></h2>
<h3>Addition</h3>
<p id="addition"></p>
<h3>Subtraction</h3>
<p id="subtraction"></p>
<h3>Multiplication</h3>
<p id="multiplication"></p>
<h3>pision</h3>
<p id="pision"></p>
<script src="functions.js"></script>
<script src="script.js"></script>
</body>
</html>这个页面很简单,就不详细说明了。
functions.js function sum(x, y) {
return x + y
}
function difference(x, y) {
return x - y
}
function product(x, y) {
return x * y
}
function quotient(x, y) {
return x / y
}最后, script.js const x = 10
const y = 5
document.getElementById('x').textContent = x
document.getElementById('y').textContent = y
document.getElementById('addition').textContent = sum(x, y)
document.getElementById('subtraction').textContent = difference(x, y)
document.getElementById('multiplication').textContent = product(x, y)
document.getElementById('pision').textContent = quotient(x, y)保存之后在浏览器中打开
对于只需要一些小脚本的网站,这不失为一种有效的组织代码的方法。但是这种方法存在一些问题:
在 ES6 把原生模块添加到 JavaScript 语言之前,社区曾经尝试着提供了几种解决方案。第一个解决方案是用原生 JavaScript 编写的,例如将所有代码都写在 objects 或立即调用的函数表达式(IIFE)中,并将它们放在全局命名空间中的单个对象上。这是对多脚本方法的一种改进,但是仍然存在将至少一个对象放入全局命名空间的问题,并没有使在第三方之间一致地共享代码的问题变得更加容易。 之后又出现了一些模块解决方案:CommonJS 是一种在 Node.js 实现的同步方法,异步模块定义(AMD)是一种异步方法,还有支持前面两种样式的通用方法——通用模块定义(UMD)。 这些解决方案的出现使我们可以更轻松地以包的形式共享和重用代码,也就是可以分发和共享的模块,例如 npm。但是由于存在许多解决方案,并且都不是 JavaScript 原生的,所以需要依靠 Babel、Webpack 或 Browserify之类的工具才能在浏览器中使用。 由于多文件方法存在许多问题,并且解决方案很复杂,所以开发人员对把模块化开发的方法引入 JavaScript 语言非常感兴趣。于是 ECMAScript 2015 开始支持 JavaScript module。 module 是一组代码,用来提供其他模块所使用的功能,并能使用其他模块的功能。 export 模块提供代码,import 模块使用其他代码。模块之所以有用,是因为它们允许我们重用代码,它们提供了许多可用的稳定、一致的接口,并且不会污染全局命名空间。 模块(有时称为 ES 模块)现在可以在原生 JavaScript 中使用,在本文中,我们一起来探索怎样在代码中使用及实现。 原生 JavaScript 模块JavaScript 中的模块使用
接下来把前面的的 functions.js export function sum(x, y) {
return x + y
}
export function difference(x, y) {
return x - y
}
export function product(x, y) {
return x * y
}
export function quotient(x, y) {
return x / y
}在 注意: 把 script.js import { sum, difference, product, quotient } from './functions.js'
const x = 10
const y = 5
document.getElementById('x').textContent = x
document.getElementById('y').textContent = y
document.getElementById('addition').textContent = sum(x, y)
document.getElementById('subtraction').textContent = difference(x, y)
document.getElementById('multiplication').textContent = product(x, y)
document.getElementById('pision').textContent = quotient(x, y)注意:要通过在花括号中命名单个函数来导入。 为了确保代码作为模块导入,而不是作为常规脚本加载,要在 index.html <script type="module" src="functions.js"> </script> <script type="module" src="script.js"> </script> 由于受限于 CORS 策略,必须在服务器环境中使用模块,否则会出现下面的错误: Access to script at 'file:///Users/your_file_path/script.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https. 模块与常规脚本不一样的地方:
模块仍然经常与打包程序(如 Webpack)一起配合使用,用来增加对浏览器的支持和附加功能,但它们也可以直接用在浏览器中。 接下来探索更多使用 命名导出如前所述,使用 functions.js export function sum() {}
export function difference() {}这样允许你用花括号按名称导入 script.js import {sum, difference} from './functions.js'也可以用别名来重命名该函数。这样可以避免在同一模块中产生命名冲突。在这个例子中, script.js import {
sum as add,
difference as subtract
} from './functions.js'
add(1, 2) // 3在这里调用 使用 script.js import * as mathFunctions from './functions.js' mathFunctions.sum(1, 2) // 3 mathFunctions.difference(10, 3) // 7 原始值、函数表达式和定义、异步函数、类和实例化的类都可以导出,只要它们有标识符就行: // 原始值
export const number = 100
export const string = 'string'
export const undef = undefined
export const empty = null
export const obj = {name: 'Homer'}
export const array = ['Bart', 'Lisa', 'Maggie']
// 函数表达式
export const sum = (x, y) => x + y
// 函数定义
export function difference(x, y) {
return x - y
}
// 匿名函数
export async function getBooks() {}
// 类
export class Book {
constructor(name, author) {
this.name = name
this.author = author
}
}
// 实例化类
export const book = new Book('Lord of the Rings', 'J. R. R. Tolkein')所有这些导出都可以成功被导入。接下来要探讨的另一种导出类型称为默认导出。 默认导出在前面的例子中我们导出了多个命名的导出,并分别或作为一个对象导入了每个导出,将每个导出作为对象上的方法。模块也可以用关键字 以 functions.js export default function sum(x, y) {
return x + y
}在 script.js import sum from './functions.js' sum(1, 2) // 3 不过这样做很危险,因为在导入过程中对默认导出的命名没有做任何限制。在这个例子中,默认函数被导入为 script.js import difference from './functions.js' difference(1, 2) // 3 所以一般首选使用命名导出。与命名导出不同,默认导出不需要标识符——原始值本身或匿名函数都可以用作默认导出。以下是用作默认导出的对象的示例: functions.js export default {
name: 'Lord of the Rings',
author: 'J. R. R. Tolkein',
}可以用以下命令将其作为 functions.js import book from './functions.js' 同样,下面的例子演示了如何将匿名箭头函数导出为默认导出: functions.js export default () => 'This function is anonymous' 可以这样导入: script.js import anonymousFunction from './functions.js' 命名导出和默认导出可以彼此并用,例如在这个模块中,导出两个命名值和一个默认值: functions.js export const length = 10
export const width = 5
export default function perimeter(x, y) {
return 2 * (x + y)
}可以用以下命令导入这些变量和默认函数: script.js import calculatePerimeter, {length, width} from './functions.js'
calculatePerimeter(length, width) // 30现在默认值和命名值都可用于脚本了。 总结模块化编程设计允许我们把代码分成单个组件,这有助于代码重用,同时还可以保护全局命名空间。一个模块接口可以在原生 JavaScript 中用关键字
更多编程相关知识,请访问:编程学习!! 以上就是详细了解javascript中的modules、import和export的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |
