我的编程空间,编程开发者的网络收藏夹
学习永远不晚

ECMAScript modules规范怎么写

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

ECMAScript modules规范怎么写

这篇文章主要讲解了“ECMAScript modules规范怎么写”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ECMAScript modules规范怎么写”吧!

    基本语法

    ES modules 是 JavaScript 的标准模块系统,模块是一个简单的 JavaScript 文件,在这个文件中包含 export 或者 import 关键字。export 用于将模块中声明的内容导出,import 用于从其他模块中导入。

    模块导出的4种写法

    模块导出用到的关键字是 export,它只能在模块顶层使用。模块可以导出函数、类、或其他基本类型等。模块导出有4种写法

    • 默认导出

    export default function myFunc() {}export default function () {}export default class MyClass {}export { foo as default }export default 'Hello Es modules!'
    • 行内命名导出

    export function myFunc() {}export class MyClass {}export const fooStr = 'Hello Es modules!'
    • 通过一个 export 子句批量命名导出

    function myFunc() {}class MyClass {}const fooStr = 'Hello Es modules!'export {myFunc, MyClass , fooStr } // 在这个地方一次性导出多个
    • 重新导出

    // 重新导出 other_module 中除默认导出之外的内容export * from './other_module.js'// 重新导出 other_module 中的默认导出export { default } from './other_module.js'// 重新导出 other_module 中的默认导出,并且将 other_module 中的 sayName 命名为 getName 之后再导出export { default, sayName as getName } from './other_module.js'

    虽然模块导出有4种写法,但是只有两种方式,一种默认导出,另一种是命名导出,在同一个模块中命名导出可以有多个,默认导出只能有一个,这两种方式可以混合使用。

    在软件开发的过程中,通常有多种写法能到达同一目的,但并不是每一种写法都值得推荐,模块导出也是类似的。如果在同一个模块中,即有默认导出,又有行内命名导出,还有 export 子句批量命名导出,那么你的模块很可能会变得混乱。在这里我推荐使用默认导出,并且将 export default 放在模块的末尾。如果你必须要命名导出,我推荐使用export 子句批量命名导出,并将 export 子句放在文件的末尾。

    3中模块说明符

    介绍完模块导出之后,按理说应该介绍模块导入,但我决定先介绍模块说明符,这是因为模块导入依赖模块说明符。说明符是字符串字面值,它表示导入模块的路径,说明符一共有三种类型,分别是:相对路径、绝对路径和 bare(裸 露) 模式。

    • 相对路径

    import foo from './myModule.js'import { sayName } from '../other_module.js'

    相对路径说明符以 / 、./ 、../ 开头,当使用相对路径说明符时不能省略文件的扩展名。在 web 项目开发中使用相对路径导入模块的时候,你可能省略了文件扩展名,它还是能够工作,那是因为你的项目使用了如 webpack 这样的模块打包工具。

    • 绝对路径

    import React from 'https://cdn.skypack.dev/react'

    上述代码表示从 cdn 导入模块,当使用绝对路径导入模块时,是否能省略文件扩展名,这与服务器配置相关。

    • bare(裸 露) 模式

    import React from 'react'import Foo from 'react/lib.js'

    bare 模式从 node_module 中导入模块,在 web 项目开发中,用这种说明符导入模块很常见,但是 ES modules 并不支持它,在你的项目中,你之所以能够使用它,是因为你的项目用了如 webpack 这样的模块打包工具。

    到目前为止,我已经介绍完了3种模块说明符,ES modules 只支持其中两种,分别是:相对路径和绝对路径。

    模块导入的 6 写法

    模块导入用到的关键字是 import,import 与 export 一样只能在模块顶部使用,模块说明符不能包含变量,它必须是固定的字符串字面量。模块导入有6种不同的写法,如下:

    • 默认导入

    // 你可以将 myFunc 改成任何你喜欢的变量名import myFunc from './myModule.js'
    • 将模块作为一个对象导入(即命名空间导入)

    import * as api from './myModule.js'// 通过对象的 default 属性访问 myModule.js 中的默认导出console.log(api.default)
    • 命名导入

    //   导入 myModule.js 中的fooStr import { fooStr } from './myModule.js'// 将myModule.js中默认导出命名为myFunc import { default as myFunc } './myModule.js'// 将 myModule.js中的 fooStr 命名为 myStrimport { fooStr as myStr } from './myModule.js'

    当某个模块中导出了很多内容,而你只需要用到它导出的一部分内容,你可以使用这个写法只导入你需要的部分,在做摇树优化的时候这至关重要。

    • 只加载模块,不导入任何东西

    import './myModule.js'

    不会将 myModule.js 中的任何内容导入到当前模块,但是会执行 myModule.js 模块体,这通常用于执行一些初始化操作。

    • 将默认导入与命名导入混合使用

    import myFunc, { fooStr  } from './myModule.js'
    • 将默认导入与命名空间导入混合使用

    import myFunc, * as api from './myModule.js'

    补充:同一个模块可以被多次导入,但是它的模块体只会执行一次

    ES modules的 4 个特点

    导入是导出的只读引用

    例如有个模块 A,它导出了一个变量 count,模块 B 导入模块 A 的 count,count 对模块 B 而言是只读的,所以在模块 B 中不能直接修改 count,下面用代码演示一下:

    // 模块A的代码如下:export var count = 0 // 注意:这里用的是 var 关键字// 模块B的代码如下:import { count  } from './moduleA.js'count++ //  Uncaught TypeError: Assignment to constant variable

    将上述代码放在浏览器中运行,浏览器会报错,错误类型是:TypeError。如果模块 A 导出了对象 obj,在模块 B 中不能直接给 obj 赋值,但是可以增、删、改 obj 中的属性。

    现在我已经介绍了只读的含义,下面介绍引用的含义。引用意味着在项目中多个模块用的是同一个变量,例如:模块 B 和模块 C 都导入了模块 A 的 count 和 changeCount 函数,模块 B 通过 changeCount 修改了 count 的值,模块C中的 count 会被一同修改,代码如下:

    // 模块A的代码如下:export var count = 0 export function changeCount() {count++}// 模块B的代码如下:import { count, changeCount } from './moduleA.js'changeCount ()console.log(count) // 1// 模块C的代码如下:import { count } from './moduleA.js'console.log(count) // 1

    模块 B 和模块 C 导入的是引用,而非副本,模块导出的变量在整个项目中是一个单例。

    支持循环依赖

    循环依赖指的是两个模块相互依赖,比如模块 A 导入了模块 B,模块 B 又导入了模块 A。尽管 ES modules 支持循环依赖,但应该避免,因为这会使两个模块强耦合。ES modules 支持循环依赖这是因为导入是导出的只读引用。

    导入会被提升

    如果你知道 JavaScript 函数提升,那么你很容易理解 ES modules 的导入提升。由于 ES modules 的导入会被提升到模块作用域的开头,所以你不需要先导入再使用。下面的代码可以工作:

    foo()import foo from './myModule.js'

    导出和静态导入必须位于模块的顶层

    导出必须位于模块的顶层这一点毋庸置疑,在 ECMAScript 2020 规范中添加了动态导入,它使模块导入可以不必位于模块的顶层。在后面会单独介绍动态导入,在这里介绍的是静态导入。

    ECMAScript 2020 之前,JavaScript 的 ES modules 是一个静态模块系统,它意味着模块的依赖项在你写代码的时候就确定了,不用等到代码运行阶段才确定,这让代码打包工具,如 webpack,很容易就能分析出 ES 模块中的依赖,给摇树优化提供了便利。

    即便 ECMAScript 2020 增加了动态导入,静态导入与动态导入在写法上有差异,静态导入使用 import 关键字,动态导入使用 import()。静态导入只能位于模块顶层。

    模块与常规JavaScript脚本的差异

    • 模块运行在严格模式下

    • 模块具备词法顶部作用域

    这句话的意思是,在模块中创建的变量,如:foo,不能通过 window.foo 访问。代码如下:

    var foo = 'hi'console.log(window.foo) // undefinedconsole.log(foo) // hiexport {} // 将这个文件标记成模块

    在模块中的声明的变量是针对该模块的,这意味着在模块中声明的任何变量对其他模块都不可用,除非它们被显式地导出。

    • 模块中的 this 关键字没有指向全局 this,它是 undefined,如果要在模块中访问全局 this 要使用 globalThis,在浏览器中 globalThis 是 window 对象。

    • export 和静态导入 import 只能在模块中使用

    • 在模块顶层能使用 await 关键字,在常规 JavaScript 脚本中只能在 async 函数中使用 await 关键字

    注意:由于 JavaScript 运行时会区别对待模块和常规的 JavaScript 脚本,所以在写代码的时候做好显示地标记 JavaScript 文件是模块,只要 JavaScript 文件中包含 export 或者 import 关键字,JavaScript 运行时就会认为这个文件是模块

    在浏览器中使用 ES modules

    现代浏览器支持 ES modules,你可以将 script 标签的 type 属性设置为 module 来告诉浏览器这个脚本是模块,代码如下:

    <!--外部模块--><script type="module" class="lazy" data-src="./module.js"></script><!--内联模块--><script type="module">   import {count} from './moduleA.js';   import React from 'https://cdn.skypack.dev/react'   console.log(count, React)</script>

    出于对兼容性的考虑,可能还需要 <script nomodule class="lazy" data-src=&rsquo;xxx.js&rsquo;></script>,在这里不做介绍。

    在之前介绍了模块和常规 JavaScript 脚本与运行环境无关的差异,现在来介绍在浏览器环境中二者的差异

    • 模块只会被执行一次

    不管模块被引入了多少次,它只会被执行一次,而常规的 JavaScript 脚本执行次数与它被添加到 DOM 的次数一致,添加多少次就执行多少次。比如有下面一段代码:

    <!--外部模块--><script type="module" class="lazy" data-src="./module.js"></script> <script type="module" class="lazy" data-src="./module.js"></script> <script type="module" class="lazy" data-src="./module.js"></script><!--内联模块--><script type="module">        import { count } from './module.js';</script><script class="lazy" data-src='./classic.js'></script><script class="lazy" data-src='./classic.js'></script>

    在上述代码中 module.js 只会被执行一次,classic.js 会被执行两次

    • 下载模块脚本不会阻塞 HTML 解析

    默认情况,当浏览器下载常规外部脚本时,它会暂停解析 HTML,我们可以在 script 标签上添加 defer 属性,使浏览器在下载脚本期间不暂停解析 HTML。当下载模块脚本时,浏览器默认模块脚本是 defer 的。

    下图展示了浏览器获取外部模块脚本和常规脚本的流程

    ECMAScript modules规范怎么写

    • 模块脚本通过 CORS 获取

    模块脚本以及它的依赖项是通过 CORS 获取的,当获取一个跨域的模块脚本时需要特别注意这个问题,跨域脚本的响应头 Access-Control-Allow-Origin 必须包含当前域,否则模块会获取失败,而获取常规脚本则没有这个限制。

    为了保证获取同源模块脚本时,浏览器始终带上 credentials(cookie 等),推荐给 script 标签加上 crossorigin 属性。

    动态导入

    到目前为止介绍的都是静态导入模块,静态导入必须等模块代码全部下载之后才会执行程序,这可能会使网站的首屏渲染性能下降。通过动态导入模块可以根据用户在界面上的操作按需下载资源,节省流量,动态导入在 ECMAScript 2020 正式发布,它需要用到import(),用法如下所示:

    // 通过相对路径导入import('./exportDefault.js').then((module) => {    console.log(module) // line A})// 通过绝对路径导入import('https://cdn.skypack.dev/react').then((react) => {    console.log(react) // line B})

    从上述代码可以看出 import() 的返回值是一个 promise 对象,当模块加载成功之后 promise 对象的状态会变成 fulfilled,import() 可以与 async/await 配合使用

    上述代码中的 line A 和 line B 标识的变量 module 和 react 都是 JavaScript 对象,我们可以用对象的点语法和中括号语法访问模块导出的任何方法和属性,模块的默认导出通过 default 属性名访问。

    动态导入与静态导入存在如下 3 个差异:

    • 动态导入的模块说明符可以是变量,但静态导入的模块说明符只能是字符串字面量

    • 动态导入能在模块和常规脚本中使用,但是静态导入只能在模块中使用

    • 动态导入不必位于文件的顶层,但静态导入只能位于模块的顶层

    虽然动态导入模块和静态导入模块存在差异,但它们都通过 CORS 获取模块脚本,所以在获取跨域模块脚本时,脚本的 Access-Control-Allow-Origin 响应头一定要配置正确。

    动态导入和静态导入有它们各自的使用场景。在初始渲染时要用到的模块使用静态导入,其他情况,特别是那些与用户操作相关的功能,可以使用动态导入按需加载依赖的模块,这种做法能提高首屏渲染性能,但是会降低用户操作过程中的性能。所以,哪些模块使用静态导入,哪些模块使用动态导入需要你根据实际情况考虑。

    提示:在动态导入模块时要用到 import(),看上去这像是函数调用,实际上它并不是函数调用,而是一种特殊的语法,你不能使用 import.call()、import.apply()、const myImport = import; myImport()。

    感谢各位的阅读,以上就是“ECMAScript modules规范怎么写”的内容了,经过本文的学习后,相信大家对ECMAScript modules规范怎么写这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    ECMAScript modules规范怎么写

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    ECMAScript modules规范怎么写

    这篇文章主要讲解了“ECMAScript modules规范怎么写”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ECMAScript modules规范怎么写”吧!基本语法ES module
    2023-07-04

    ECMAScript modules规范示例详解

    这篇文章主要为大家介绍了ECMAScript modules规范示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-16

    css中BEM怎么书写规范

    这篇文章主要介绍“css中BEM怎么书写规范”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“css中BEM怎么书写规范”文章能帮助大家解决问题。BEM是基于组件的web开发方法。其思想是将用户界面分隔
    2023-07-04

    shell脚本的编写规范是怎样的

    这篇文章主要介绍“shell脚本的编写规范是怎样的”,在日常操作中,相信很多人在shell脚本的编写规范是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”shell脚本的编写规范是怎样的”的疑惑有所帮助!
    2023-06-09

    java开发文档编写规范是什么

    Java开发文档编写规范是一套规范,用于指导Java开发人员编写清晰、一致和易于理解的文档。以下是一些常见的Java开发文档编写规范:1. 使用规范的注释格式:在代码中使用注释,描述类、方法和变量的功能以及用法,并使用规范的注释格式,如Ja
    2023-08-28

    C语言的基本编写规范是什么

    C语言的基本编写规范是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。C语言是什么C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,使用C语言可以以简易的
    2023-06-26

    阿里规范不建议多表Join,可这SQL要怎么写?

    阿里开发手册的描述,禁止多表join:手册上写着【强制】,相信很多同学项目里面的代码都不满足这个要求。但是关键问题是:不用join,这SQL究竟要怎么写?!分解关联查询即对每个要关联的表进行单表查询,然后将结果在应用程序中进行关联。下面的这个查询:SELECT
    阿里规范不建议多表Join,可这SQL要怎么写?
    2019-04-10

    @Valid注解怎么规范使用

    这篇文章主要介绍“@Valid注解怎么规范使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“@Valid注解怎么规范使用”文章能帮助大家解决问题。@Valid注解大全及用法规范注解描述@Assert
    2023-06-29

    PHP 函数文档编写规范的目的是什么?

    php 函数文档编写规范旨在确保文档清晰一致且有用,包括:函数名称:动词开头的驼峰式命名法。参数:类型、名称和描述。返回值:数据类型和异常。异常:可能引发的异常及其原因。示例:显示函数使用方式的代码。描述:函数行为的简要描述。PHP 函数文
    PHP 函数文档编写规范的目的是什么?
    2024-04-27

    为什么 PHP 函数文档应当遵循编写规范?

    php 函数文档编写规范至关重要,规范主要涉及模块化分段、清晰简要的语言、详细的参数描述、明确的返回值信息以及提供代码示例。规范化文档可提升一致性和可读性,从而降低开发成本并提高代码质量。PHP 函数文档编写规范的重要性引言高质量的函数文
    为什么 PHP 函数文档应当遵循编写规范?
    2024-04-27

    网页制作过程中代码注释书写规范是怎么样的

    小编给大家分享一下网页制作过程中代码注释书写规范是怎么样的,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!总结了一下自己工作中使用到的注释书写规范,没有什么技术含量
    2023-06-08

    HTML中head头部区域的编码书写规范是什么

    这篇文章主要讲解了“HTML中head头部区域的编码书写规范是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“HTML中head头部区域的编码书写规范是什么”吧!head区一般必须加入的标
    2023-06-27

    Flex代码规范中MDI框架怎么用

    小编给大家分享一下Flex代码规范中MDI框架怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Flex代码规范1.MDI框架使用1.1.初始化参数处理函数注册窗口初始化事件:MessagesManager.getIns
    2023-06-17

    vue项目代码格式规范怎么设置

    本篇内容主要讲解“vue项目代码格式规范怎么设置”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue项目代码格式规范怎么设置”吧!为项目添加eslint使用vue-cli构建的项目,在项目构建时
    2023-06-30

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录