0

0

详细了解javascript中的modules、import和export

青灯夜游

青灯夜游

发布时间:2020-12-04 17:35:05

|

9780人浏览过

|

来源于segmentfault

转载

详细了解javascript中的modules、import和export

在互联网的洪荒时代,网站主要用 HTML和 CSS 开发的。如果将 JavaScript 加载到页面中,通常是以小片段的形式提供效果和交互,一般会把所有的 JavaScript 代码全都写在一个文件中,并加载到一个 script 标签中。尽管可以把 JavaScript 拆分为多个文件,但是所有的变量和函数仍然会被添加到全局作用域中。

但是后来 JavaScript 在浏览器中发挥着重要的作用,迫切需要使用第三方代码来完成常见任务,并且需要把代码分解为模块化的文件,避免污染全局命名空间。

ECMAScript 2015 规范在 JavaScript 语言中引入了 module,也有了 import 和 export 语句。在本文中,我们一起来学习 JavaScript 模块,以及怎样用 importexport 来组织代码。

模块化编程

在 JavaScript 中出现模块的概念之前,当我们想要把自己的代码组织为多个块时,一般会创建多个文件,并且将它们链接为单独的脚本。下面先举例说明,首先创建一个 index.html 文件和两个JavaScript文件“ functions.jsscript.js

立即学习Java免费学习笔记(深入)”;

index.html 文件用来显示两个数字的和、差、乘积和商,并链接到 script 标签中的两个 JavaScript 文件。打开 index.html 并添加以下代码:

index.html



  
    
    

    JavaScript Modules
  

  
    

Answers

and

Addition

Subtraction

Multiplication

pision

这个页面很简单,就不详细说明了。

functions.js 文件中包含将会在第二个脚本中用到的数学函数。打开文件并添加以下内容:

functions.js

广研企业网站管理系统中英文双语版
广研企业网站管理系统中英文双语版

v1.8新增功能简介: 一、后台新增生成网站地图和生成Sitemap.xml的功能。 二、新增下载中心功能,可在后台上传doc,xls,ppt,rar,pdf文件。 三、新增产品缩略图自动缩放功能,图片按比例缩放,解决了图片变形问题。 四、新闻、产品详细页新增了上一个、下一个的功能,改善用户体验。 五、在线客服新增了阿里巴巴贸易通在线客服。 六、可在后台设置分享代码,如百度分享和AddThis等。

下载
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 文件用来确定 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)

保存之后在浏览器中打开 index.html 可以看到所有结果:

1.png

对于只需要一些小脚本的网站,这不失为一种有效的组织代码的方法。但是这种方法存在一些问题:

  • 污染全局命名空间:你在脚本中创建的所有变量(sumdifference 等)现在都存在于 window 对象中。如果你打算在另一个文件中使用另一个名为 sum 的变量,会很难知道在脚本的其它位置到底用的是哪一个值变量,因为它们用的都是相同的 window.sum 变量。唯一可以使变量私有的方法是将其放在函数的作用域中。甚至在 DOM 中名为 xid 可能会和 var x 存在冲突。
  • 依赖管理:必须从上到下依次加载脚本来确保可以使用正确的变量。将脚本分别保存存为不同文件会产生分离的错觉,但本质上与放在页面中的单个 中相同。

在 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 中的模块使用importexport 关键字:

  • import:用于读取从另一个模块导出的代码。
  • export:用于向其他模块提供代码。

接下来把前面的的 functions.js 文件更新为模块并导出函数。在每个函数的前面添加 export

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 从前面的 functions.js 模块中检索代码。

注意:import 必须始终位于文件的顶部,然后再写其他代码,并且还必须包括相对路径(在这个例子里为 ./)。

script.js 中的代码改成下面的样子:

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"。任何使用 importexport 的代码都必须使用这个属性:

index.html


由于受限于 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.

模块与常规脚本不一样的地方:

  • 模块不会向全局(window)作用域添加任何内容。
  • 模块始终处于严格模式。
  • 在同一文件中把同一模块加载两次不会出问题,因为模块仅执行一次
  • 模块需要服务器环境。

模块仍然经常与打包程序(如 Webpack)一起配合使用,用来增加对浏览器的支持和附加功能,但它们也可以直接用在浏览器中。

接下来探索更多使用 importexport 语法的方式。

命名导出

如前所述,使用 export 语法允许你分别导入按名称导出的值。以这个 function.js 的简化版本为例:

functions.js

export function sum() {}
export function difference() {}

这样允许你用花括号按名称导入 sumdifference

script.js

import {sum, difference} from './functions.js'

也可以用别名来重命名该函数。这样可以避免在同一模块中产生命名冲突。在这个例子中,sum 将重命名为 add,而 difference 将重命名为 subtract

script.js

import {
  sum as add,
  difference as subtract
} from './functions.js'

add(1, 2) // 3

在这里调用 add() 将产生 sum() 函数的结果。

使用 * 语法可以将整个模块的内容导入到一个对象中。在这种情况下,sumdifference 将成为 mathFunctions 对象上的方法。

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')

所有这些导出都可以成功被导入。接下来要探讨的另一种导出类型称为默认导出。

默认导出

在前面的例子中我们导出了多个命名的导出,并分别或作为一个对象导入了每个导出,将每个导出作为对象上的方法。模块也可以用关键字 default 包含默认导出。默认导出不使用大括号导入,而是直接导入到命名标识符中。

functions.js 文件为例:

functions.js

export default function sum(x, y) {
  return x + y
}

script.js 文件中,可以用以下命令将默认函数导入为 sum

script.js

import sum from './functions.js'

sum(1, 2) // 3

不过这样做很危险,因为在导入过程中对默认导出的命名没有做任何限制。在这个例子中,默认函数被导入为 difference,尽管它实际上是 sum 函数:

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',
}

可以用以下命令将其作为 book 导入:

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 中用关键字 importexport 来实现。

原文地址:https://www.taniarascia.com/javascript-modules-import-export/

作者:Tania Rascia

译文地址:https://segmentfault.com/a/1190000038275195

更多编程相关知识,请访问:编程学习!!

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

553

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

731

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

477

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

990

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

656

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

551

2023.09.20

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

36

2026.01.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.2万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号