资讯专栏INFORMATION COLUMN

ES6深入浅出 模块系统

Lionad-Morotar / 2116人阅读

摘要:默认导出可以使用进行默认导出注意一个模块中只可以有一个默认导出。尽管这种模块的顶级变量函数或类最终并不会自动被加入全局作用域,但这并不意味着该模块无法访问全局作用域。

一步,一步前進の一步。

模块化主要是帮助我们更好的组织代码,模块允许我们将相关的变量和函数放在一个模块中。在 ES6 模块化之前,JS 语言并没有模块的概念,只有函数作用域和全局作用域非常容易发生命名冲突。之前的 RequireJSSeaJSAMDUMDCMD啥的,在一定层面上都是为了解决 JS 模块化的问题。

笔者是一个也不会用啊(技术发展太快了,新技术学不过来,还是坐等它们过时吧,果然 webpack 和 es6替代了它们),一步心中有个期待,啥时候我们用的 ES6、ES7直接运行在浏览器上吧,我现在还坐等 webpack 和 babel 死掉呢,一点还不会呢。

什么是模块

模块是自动运行在严格模式下的JS 代码,在模块中创建的变量不会被添加到全局共享作用域,这个变量只会存在于模块的作用域中,在模块中 this的值是 undefined。模块的真正魔力所在是仅导入导出你需要的绑定,而不是将所用的东西都放在一个地方。一个文件即一个模块。

严格模式

模块中的代码是在严格模式下运行的,等同于在文件的顶部use strict。JS 在严格模式下使用会更加的严谨。简单列举几条严格模式的规则:

变量使用前必须声明

函数不能有重名参数

with 不允许使用

。。。
更多规则请参考阮一峰老师的文章严格模式

export

在 ES6模块中的声明的作用范围就被限定在了模块文件中,文件外部是无法访问的,必须使用 export关键字将引用显示的暴露出去。

默认导出

可以使用 export default进行默认导出,注意一个模块中只可以有一个默认导出。

export default 1
export default NaN
export default "foo"
export default { foo: "bar" }
export default ["foo", "bar"]
命名导出

命名导出和默认导出同样常用,如果一个模块想要导出多个声明时较为常用,使用如下:

export var foo = "bar"
export var baz = "ponyfoo"
导出是绑定

需要注意的是 ES6模块导出的是绑定关联,不是值的复制,意味着如果你导出一个变量 foo,那么 foo 是和模块内部是相互关联连动的,我个人反对去更改一个模块所暴露出来的接口(export出来的部分)。

假设你有个模块./a,导出的 foo 变量初始值是 bar 将在500ms 变成 baz,在使用该变量的地方(import处)也会有该变化。

export var foo = "bar"
setTimeout(() => foo = "baz", 500)
导出列表

ES6 的模块允许你导出一个命名导出列表,代码片段如下:

var foo = "ponyfoo"
var bar = "baz"
export { foo, bar }

同时可以对命名导出进行重命名:

export { foo as ponyfoo }
导出的最佳实践

我们学会了命名导出导出列表默认导出导出重命名,此时你应该有点疑惑,我该选择那种方式实现自己的导出呢?人呐之所以烦恼,就是因为选择太多了。作者推荐大家在文件的尾部使用export default进行默认导出。

var foo = "ponyfoo"
var bar = "baz"
...

var api = {
  foo,
  baz,
  ...
}
export default api

这样做的好处如下:

模块中导出的部分变得显而意见,不需要从头到尾去找模块中哪里是私有的,哪里是需要export 出去的,只需要滚动到文件底部就可以一目了然。

不用纠结是应该使用命名导出,列表导出,还是重命名导出了,只使用export default不知道大家有没有注意到,当你将一个对象作为默认导出接口时,即可以结合命名导出,还可以重命名,还能支持导出多个。

import

import 关键字的作用和 export 的作用正好相反,import 的作用是当年想使用其他模块中的内容时进行关系绑定。

导入默认导出

当想在另一个模块中使用上一个模块的默认导出时十分方便,impprt 后面的名字可以随便起,代码如下:

import _ from "lodash"
import lodash from "lodash"
导入命名导出

import关键字后面使用花括号包上你想要使用的命名导出。

import {map, reduce} from "lodash"

导入时也可以进行重命名

import {cloneDeep as clone, map} from "lodash"
完全导入一个模块
import * as _ from "lodash"
//使用时采用_.的形式
_.map()
无绑定的导入

有些模块也许没有进行任何导出,相反只是修改全局作用域的对象。尽管这种模块的顶级变 量、函数或类最终并不会自动被加入全局作用域,但这并不意味着该模块无法访问全局作用 域。

加载模块

虽然我们日常编码中在使用 ES6的 import和 export 关键字,但是仔细想一下,我们并不了解 ES6的模块是如何加载的,只知道打包工具帮我们处理好了,实际上我们并不了解模块化的知识。有时间再更新

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96852.html

相关文章

  • 【翻译】深入理解ES6模块

    摘要:你可能认为和它的新模块系统出现得有点晚。聚合模块有时候一个包的主模块只不过是导入包其他所有的模块,并用统一的方式导出。静态动态,或者说规则如何打破规则作为一个动态编译语言,令人惊奇的是拥有一个静态的模块系统。 回想2007年,那时候我刚加入Mozillas JavaScript团队,那时候的一个典型的JavaScript程序只需要一行代码,听起来像个笑话。 两年后,Google Map...

    icattlecoder 评论0 收藏0
  • ES6-7

    摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...

    mudiyouyou 评论0 收藏0
  • 带你了解JavaScript相关的模块机制

    摘要:本文从最简单的模块开始,然后主要从的模块规范和的模块机制对模块进行梳理。对象的属性模块的识别符,通常是带有绝对路径的模块文件名。返回一个对象,表示调用该模块的模块。表示模块对外输出的值。可见当删除了相关模块的缓存再一次加载时则不再有了。 前言 java有类文件,Python有import机制,Ruby有require等,而Javascript 通过标签引入代码的机制显得杂乱无章,语言自...

    ningwang 评论0 收藏0
  • 前端构建工具整理

    摘要:常见前端构建工具的分类和对比是附带的包管理器,是内置的一个功能,允许在文件里面使用字段定义任务在这里,一个属性对应一段脚本,原理是通过调用去运行脚本命令。 前文 端技术范围不断发展,前端开发不仅限于直接编写html,css和javascript,Web应用日益庞大,代码也更加庞大,因此许多新的思想(例如模块化和工程化等)和框架(React和Vue等),以及新的语言(Es6 TypeSc...

    leo108 评论0 收藏0
  • 面试深入一、ES6模块化、安装和打包

    摘要:开发环境已经普及使用浏览器环境却支持不好需要开发环境编译内容很多,重点了解常用语法面试开发环境的使用重点语法的掌握问题模块化如何使用,开发环境如何打包和普通构造函数有何区别的基本使用和原理总结一下其他常用功能模块化的基本语法开发环境电脑有 ES6 开发环境已经普及使用 浏览器环境却支持不好(需要开发环境编译) 内容很多,重点了解常用语法 面试:开发环境的使用 + 重点语法的掌握 ...

    verano 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<