ES6中模块Module的详细介绍(附示例)

本篇文章给大家带来的内容是关于ES6中模块Module的详细介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

这篇文章主要介绍了ES6新特性之模块Module用法,简要说明了模块Module的概念、功能并结合实例形式分析了模块Module的使用方法与相关注意事项,需要的朋友可以参考下

一、Module简介

ES6的Class只是面向对象编程的语法糖,升级了ES5的构造函数的原型链继承的写法,并没有解决模块化问题。Module功能就是为了解决这个问题而提出的。

历史上,JavaScript一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能。

在ES6之前,社区制定了一些模块加载方案,最主要的有CommonJS和AMD两种。前者用于服务器,后者用于浏览器。ES6在语言规格的层面上,实现了模块功能,而且实现得相当简单,完全可以取代现有的CommonJS和AMD规范,成为浏览器和服务器通用的模块解决方案。

ES6模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系(这种加载称为“编译时加载”),以及输入和输出的变量。CommonJS和AMD模块,都只能在运行时确定这些东西。
浏览器使用ES6模块的语法如下。


登录后复制

上面代码在网页中插入一个模块fs.js,由于type属性设为module,所以浏览器知道这是一个ES6模块。

// ES6加载模块import { stat, exists, readFile } from 'fs';

登录后复制

上面代码通过import去加载一个Module,加载其中的一些方法。

二、import 和 export

模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个JS文件,里面使用export命令输出变量。

// profile.jsexport var firstName = 'Michael';export var lastName = 'Jackson';export var year = 1958;

登录后复制

export的写法,除了像上面这样,还有另外一种。(推荐这种,因为这样就可以在脚本尾部,一眼看清楚输出了哪些变量。)

// profile.jsvar firstName = 'Michael';var lastName = 'Jackson';var year = 1958;export {firstName, lastName, year};

登录后复制

export命令除了输出变量,还可以输出函数或类(class)。通常情况下,export输出的变量就是本来的名字,但是可以使用as关键字重命名。

function v1() { ... }function v2() { ... }export {  v1 as streamV1,  v2 as streamV2,  v2 as streamLatestVersion};

登录后复制

使用export命令定义了模块的对外接口以后,其他JS文件就可以通过import命令加载这个模块(文件)。

// main.jsimport {firstName, lastName, year} from './profile';function setName(element) {  element.textContent = firstName + ' ' + lastName;}

登录后复制

上面代码的import命令,就用于加载profile.js文件,并从中输入变量。import命令接受一个对象(用大括号表示),里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。
如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。

import { lastName as surname } from './profile';

登录后复制

import命令具有提升效果,会提升到整个模块的头部,首先执行。

foo();import { foo } from 'my_module';

登录后复制

三、模块的整体加载

除了指定加载某个输出值,还可以使用整体加载,即用星号(*)指定一个对象,所有输出值都加载在这个对象上面。
有一个circle.js文件,它输出两个方法area和circumference。
现在,加载这个模块。

// main.jsimport { area, circumference } from './circle';console.log('圆面积:' + area(4));console.log('圆周长:' + circumference(14));

登录后复制

上面写法是逐一指定要加载的方法,整体加载的写法如下。

import * as circle from './circle';console.log('圆面积:' + circle.area(4));console.log('圆周长:' + circle.circumference(14));

登录后复制

四、export default

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

// export-default.jsexport default function () {  console.log('foo');}

登录后复制

上面代码是一个模块文件export-default.js,它的默认输出是一个函数。
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

// import-default.jsimport customName from './export-default';customName(); // 'foo'

登录后复制

需要注意的是,这时import命令后面,不使用大括号。
本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。它后面不能跟变量声明语句。

// 正确var a = 1;export default a;// 错误export default var a = 1;

登录后复制

五、ES6模块加载的实质

ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。
CommonJS模块输出的是被输出值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。请看下面这个模块文件lib.js的例子。

// lib.jsvar counter = 3;function incCounter() { counter++;}module.exports = { counter: counter, incCounter: incCounter,};

登录后复制

上面代码输出内部变量counter和改写这个变量的内部方法incCounter。然后,在main.js里面加载这个模块。

// main.jsvar mod = require('./lib');console.log(mod.counter); // 3mod.incCounter();console.log(mod.counter); // 3

登录后复制

上面代码说明,lib.js模块加载以后,它的内部变化就影响不到输出的mod.counter了。这是因为mod.counter是一个原始类型的值,会被缓存。除非写成一个函数,才能得到内部变动后的值。

// lib.jsvar counter = 3;function incCounter() { counter++;}module.exports = { get counter() {  return counter }, incCounter: incCounter,};

登录后复制

上面代码中,输出的counter属性实际上是一个取值器函数。现在再执行main.js,就可以正确读取内部变量counter的变动了。
ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,换句话说,ES6的输入有点像Unix系统的“符号连接”,原始值变了,import输入的值也会跟着变。因此,ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
还是举上面的例子。

// lib.jsexport let counter = 3;export function incCounter() { counter++;}// main.jsimport { counter, incCounter } from './lib';console.log(counter); // 3incCounter();console.log(counter); // 4

登录后复制

上面代码说明,ES6模块输入的变量counter是活的,完全反应其所在模块lib.js内部的变化。
由于ES6输入的模块变量,只是一个“符号连接”,所以这个变量是只读的,对它进行重新赋值会报错。

// lib.jsexport let obj = {};// main.jsimport { obj } from './lib';obj.prop = 123; // OKobj = {}; // TypeError

登录后复制

上面代码中,main.js从lib.js输入变量obj,可以对obj添加属性,但是重新赋值就会报错。因为变量obj指向的地址是只读的,不能重新赋值,这就好比main.js创造了一个名为obj的const变量。
最后,export通过接口,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例。

// mod.jsfunction C() { this.sum = 0; this.add = function () {  this.sum += 1; }; this.show = function () {  console.log(this.sum); };}export let c = new C();

登录后复制

上面的脚本mod.js,输出的是一个C的实例。不同的脚本加载这个模块,得到的都是同一个实例。

// x.jsimport {c} from './mod';c.add();// y.jsimport {c} from './mod';c.show();// main.jsimport './x';import './y';

登录后复制

现在执行main.js,输出的是1。这就证明了x.js和y.js加载的都是C的同一个实例。

以上就是ES6中模块Module的详细介绍(附示例)的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2735717.html

(0)
上一篇 2025年3月8日 01:18:06
下一篇 2025年3月6日 02:09:34

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • passive的原理是什么?有什么作用?

    本篇文章给大家带来的内容是关于passive的原理是什么?有什么作用?有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 passived到底有什么用? passived主要用于优化浏览器页面滚动的性能,让页面滚动更顺滑~~ p…

    2025年3月8日
    200
  • JavaScript如何使用setTimeout()设置定时器

    在javascript中,通过给settimeout()方法设置需要调用的函数或要执行的代码串参数,和延迟的时间参数;在调用settimeout()方法就可以设置一个简单的定时器。 在JS中,提供了一些原生方法来实现在设定的时间间隔之后去执…

    2025年3月8日
    200
  • JavaScript中Object.create()的用法介绍

    本篇文章给大家带来的内容是关于JavaScript中Object.create()的用法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 Object.create(null) 创建的对象是一个空对象,在该对象上没有继承…

    编程技术 2025年3月8日
    200
  • JavaScript中Proxy的详细介绍(代码示例)

    本篇文章给大家带来的内容是关于javascript中proxy的详细介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 Proxy 让我们可以对任何对象的绝大部分行为进行监听和干涉,实现更多的自定义程序行为。 …

    编程技术 2025年3月8日
    200
  • JavaScript中Reflect的详细介绍(附示例)

    本篇文章给大家带来的内容是关于JavaScript中Reflect的详细介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 Reflect 是一个内置的对象,它提供可拦截JavaScript操作的方法。方法与代理…

    编程技术 2025年3月8日
    200
  • JavaScript中import的详解(附示例)

    本篇文章给大家带来的内容是关于javascript中import的详解(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 import 语句用于导入由另一个模块导出的绑定。无论是否声明了 strict mode,导入…

    编程技术 2025年3月8日
    100
  • redux的核心讲解(代码示例)

    本篇文章给大家带来的内容是关于redux的核心讲解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 概念 redux是一种架构模式,可以和react、vue结合使用。 解决的问题 优雅地修改共享数据状态,避免状态…

    2025年3月8日
    200
  • Vue封装ajax的代码示例详解

    本篇文章给大家带来的内容是关于vue封装ajax的代码示例详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 HTML文件: Document 点击获取信息 {{ msg }} var vm=new Vue({ el: “…

    编程技术 2025年3月8日
    200
  • JavaScrip的常见面试题及答案总结

    本篇文章给大家带来的内容是关于javascrip的常见面试题及答案总结,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 一、请解释 JavaScript 中 this 是如何工作的。 首先:this 永远指向函数运行时所在的…

    编程技术 2025年3月8日
    200
  • JavaScript中let、var和const的区别及应用场景的介绍

    在javascript中,建议在使用变量和常量时声明变量名称(下面统称为“变量”)。var,let和const是在javascript中声明变量时使用的关键字,其中,let和const是ecmascript 2015采用的新声明方法的关键字…

    2025年3月8日
    200

发表回复

登录后才能评论