ES6深入浅出 模块系统

2018-08-12 admin

一步,一步前進の一步。

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

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

什么是模块

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

严格模式

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

  1. 变量使用前必须声明
  2. 函数不能有重名参数
  3. 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

这样做的好处如下:

  1. 模块中导出的部分变得显而意见,不需要从头到尾去找模块中哪里是私有的,哪里是需要export 出去的,只需要滚动到文件底部就可以一目了然。
  2. 不用纠结是应该使用命名导出,列表导出,还是重命名导出了,只使用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的模块是如何加载的,只知道打包工具帮我们处理好了,实际上我们并不了解模块化的知识。有时间再更新👻。 。。。。

原文ES6 Modules in Depth

🌚 前端学习QQ群: 538631558 🌚

【开发环境推荐】Cloud Studio 是基于浏览器的集成式开发环境,支持绝大部分编程语言,包括 HTML5、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,无需下载安装程序,一键切换开发环境。 Cloud Studio提供了完整的 Linux 环境,并且支持自定义域名指向,动态计算资源调整,可以完成各种应用的开发编译与部署。

原文链接:https://segmentfault.com/a/1190000015975684

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-37786.html

文章标题:ES6深入浅出 模块系统

相关文章
canvas图片绘制跨域问题解决方案Tainted canvases may not be exported
图片跨域问题的一般解决方法 当使用canvas绘制网络图片的时候,经常会出现“Tainted canvases may not be exported”报错,上网搜一下解决方案,应该给的都是给img添加crossOrigin属性,尝试了一下...
2018-04-19
Vue.js原理分析之observer模块详解
介绍 observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。 **注意:**本文是针对Vue@2.1.8进行分析 observer模块在Vue项目中的代码位置是src/c...
2017-03-16
详解JavaScript ES6中的Generator
今天讨论的新特性让我非常兴奋,因为这个特性是 ES6 中最神奇的特性。 这里的“神奇”意味着什么呢?对于初学者来说,该特性与以往的 JS 完全不同,甚至有些晦涩难懂。从某种意义上说,它完全改变了这门语言的通常行为,这不是“神奇”是什么呢。 ...
2017-03-27
localResizeIMG先压缩后使用ajax无刷新上传(移动端)
下面通过文字说明和代码分析的方式给大家分享移动端图片上传之localResizeIMG先压缩后ajax无刷新上传,具体实现过程请看下文。 现在科技太发达,移动设备像素越来越高,随便一张照片2M+,但是要做移动端图片上传和pc上略有不同,移动...
2017-03-29
JS中处理时间之setUTCMinutes()方法的使用
javascript Date.setUTCMinutes()方法按照通用时间设置分钟为一个指定日期。 语法 Date.setUTCMinutes(minutesValue[, secondsValue[, msValue]]) 注:括号...
2017-03-24
简介JavaScript中toTimeString()方法的使用
该方法返回一个Date对象在人类可读的形式时间部分。 语法 下面是参数的详细信息: 返回值: 返回Date对象的人类可读形式的时间部分。 例子: <html> <head> <title>JavaScri...
2017-03-24
浅析Node.js的Stream模块中的Readable对象
我一直都很不愿意扯 nodejs 的流,因为从第一次看到它我就觉得它的设计实在是太恶心了。但是没办法,Stream 规范尚未普及,而且确实有很多东西都依赖了 nodejs 的流来实现的,所以我也只能捏着鼻子硬着头皮来扯一扯这又臭又硬的 no...
2017-03-27
vue-awesome-swiper的使用以及API整理
一、先说一个看关于vue-awesome-swiper的一个坑 vue项目的package.json中显示的<span style=“color: orange;”>“vue-awesome-swiper”: “^2.5.4”&...
2018-04-26
javascript获取本机操作系统类型的方法
废话不多说了,下面通过一段代码示例介绍一下,希望能够给需要的朋友带来或多或少的帮助。 示例代码: function GetOSInfo() { var _pf=navigator.platform; var appVer=navig...
2017-03-29
在JavaScript中处理时间之setMinutes()方法的使用
javascript Date.setMinutes()方法按照本地时间的设置分钟为一个指定日期 语法 Date.setMinutes(minutesValue[, secondsValue[, msValue]]) 注:括号内外观和数据...
2017-03-24
回到顶部