什么是模块?深刻理解ES6模块
1.模块
1.1 什么是模块?什么是模块化?
玩过FPS游戏的朋友应该知道,一把装配完整的M4步枪,一般是枪身+消音器+倍镜+握把+枪托
。
如果把M4步枪看成是一个页面的话,那么我们可以做如下类比枪身 -> <main></main>
消音器 -> <header></header>
倍镜 -> <nav></nav>
握把 -> <aside></aside>
枪托 -> <footer></footer>
OK,你刚才做了一件事情,就是把m4步枪拆成了五个部分,你拆分的每一个部分就是一个模块【module】,你拆分的这个过程就是模块化【modularization】。
模块化是一种编程思想,其核心就是拆分任务,把复杂问题简单化,这样一来既方便多人分工协作,又可以帮助我们迅速定位问题
方便多人分工协作 —— 可以不同的人开发不同的模块,再组合,大大增加团队效率
帮助我们迅速定位问题 —— 后坐力太大,那八成是枪托或握把的问题;声音过大,那八成是消音器的问题。
1.2 模块化的血泪史
下面用一个小栗子讲一讲模块化的发展史
龚先生和棚先生一起接了一个项目,他们俩需要分别实现一些功能,很简单,就是Console出来自己的变量a
于是他们俩一合计,安排龚先生的代码单独放在script1.js
里写,棚先生的代码单独放在script2.js
里写,然后用script标签分别引入
// script1.js文件 var a = 1 console.log(a)
// script2.js文件 var a = 2 console.log(a)
<!--HTML文件--> <script src="./script1.js"></script> <script src="./script2.js"></script>
很快他们遇到了第一个问题 —— 变量命名冲突
尤其是包含了异步的时候,会出现如下情况
// script1.js文件 var a = 1 setTimeout(()=>{ console.log(a) // 我们想console出来1,却console出了2 },1000)
// script2.js文件 var a = 2 console.log(a)
上面的问题明显是由于a是一个全局变量导致的,所以解决思路也很明确——造一个局部变量呗
局部变量
ES5时代使用立即执行函数制造局部变量
// script1.js文件 !function(){ var a = 1 setTimeout(()=>{ console.log(a) // 这下是2了 },1000) }() // 下面有5000行代码
// script2.js文件 console.log(2)
ES6时代直接使用块级作用域+let
// script1.js文件 { let a = 1 setTimeout(()=>{ console.log(a) // 这下是2了 },1000) }
// script2.js文件 { let a = 2 console.log(a) }
通过window连接各个模块
后来公司招了一个前端大佬,说现在只能由他来控制什么时候console变量,于是他新建了一个control.js
文件
并通过window对象连接script1.js和scirpt2.js
// script1.js文件 { let a = 1 window.module1 = function() { console.log(a) } }
// script2.js文件 { let a = 2 window.module2 = function() { console.log(a) } }
// control.js文件 setTimeout(()=>{ window.module1() },1000) window.module2()
这个时候,非常重要的一点就是window是一个全局变量并且充当了一个公用仓库,这个仓库有两个关键作用,存【导出】
和取【依赖】
// script1.js文件 { let a = 1 // 把这个函数存放进window,就是导出到window window.module1 = function() { console.log(a) } }
// control.js文件 setTimeout(()=>{ // 我们从window里取出module1函数进行调用,就是依赖了script1.js文件 window.module1() },1000) window.module2()
依赖加载的顺序
烦人的产品对需求又进行了更改,给了一个name.js文件
// name.js文件 window.names = ['gongxiansheng','pengxiansheng']
要求现在龚先生和棚先生需要Console出自己的名字
这还不简单?几秒钟写好
// script1.js文件 { window.module1 = function() { console.log(window.names[0]) } }
// script2.js文件 { window.module2 = function() { console.log(window.names[1]) } }
// control.js文件 setTimeout(()=>{ window.module1() },1000) window.module2()
<!--HTML文件--> <script src="./script1.js"></script> <script src="./script2.js"></script>
但很快他们发现,console出来的都是undefined
前端大佬一眼看出了问题,对他们俩说你们依赖的代码一定要在你们自己的代码前引入,不然是取不到值的;你看我的control.js是不是在你们俩的代码后面引入的,因为我用到了你们俩的代码了呀
噢噢,原来是js文件加载顺序问题,改一下吧
<!--HTML文件--> <script src="./name.js"></script> <script src="./script1.js"></script> <script src="./script2.js"></script> <script src="./control.js"></script>
但是在人多了以后,我们到时候会搞不清楚到底谁依赖了谁,保险起见只能全部都加载,性能浪费了太多
,前端大佬摇头叹息道
2. ES6的模块
2.1 ES6之前模块化的痛点
变量冲突
要用window连接各个模块
依赖需要全部加载
还要TMD注意加载顺序
模块化是ES6的最大的亮点之一,因为在ES6之前的语法里从未有过模块化的体系,这对开发大型的、复杂的项目形成了巨大障碍。因为我们无法对项目进行拆分,无法更好地进行多人协作开发。更重要的是,其它大部分语言都支持模块化。
既然语言不支持,那么如何将模块化引入JS呢?
前端社区就自己制定了一些模块加载方案——这也是CommonJS【服务器】和AMD、CMD【浏览器】的由来。
但是现在ES6引入了模块化的功能,实现起来非常简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
2.2 import和export的用法
import和export语法较为简单,大家去MDN可以看非常详细的讲解,笔者在这里知识用注释简单介绍一下
export语法
// 命名导出 export { name1, name2, …, nameN }; export { variable1 as name1, variable2 as name2, …, nameN }; export let name1, name2, …, nameN; // also var export let name1 = …, name2 = …, …, nameN; // also var, const export function FunctionName() {...} export class ClassName {...} // 默认导出 export default expression; export default function (…) { … } // also class, function* export default function name1(…) { … } // also class, function* export { name1 as default, … }; // 将其它模块内的导出作为当前文件的导出 export * from …; export { name1, name2, …, nameN } from …; export { import1 as name1, import2 as name2, …, nameN } from …;
import用法
import defaultExport from "module-name"; // 导入默认默认变量 import * as name from "module-name"; // 将模块内所有变量导出,并挂载到name下【name是一个module对象】。什么要有as——为了防止export出来的变量命名冲突 import { export } from "module-name"; // 导入某一个变量 import { export as alias } from "module-name"; // 导入某一个变量并重命名 import { export1 , export2 } from "module-name"; // 导入两个变量 import { export1 , export2 as alias2 , [...] } from "module-name"; // 导入多个变量,同时可以给导入的变量重命名 import defaultExport, { export [ , [...] ] } from "module-name"; // 导入默认变量和多个其它变量 import defaultExport, * as name from "module-name"; // 导入默认变量并重新命名 import "module-name"; // 导入并加载该文件【注意文件内的变量必须要通过export才能被使用】 var promise = import(module-name); // 异步的导入
使用import和export改写第一节的代码
// name.js文件 let names = ['gongxiansheng','pengxiansheng'] export default names
// script1.js import names from './name.js' let module1 = function () { console.log(names[0]) } export default module1
// script2.js import names from './name.js' let module2 = function() { console.log(names[1]) } export default module2
// control.js import module1 from './script1.js' import module2 from './script2.js' setTimeout(() => { module1() }, 1000) module2()
<!--HTML文件--> <script type="module" src="./control.js"></script> <!--注意一定要加上type="module",这样才会将这个script内的代码当做模块来对待-->
2.3 拓展:import和export的一些运行原理
2.3.1 ES6 模块输出的是值的引用,输出接口会动态绑定
其实就是按照数据类型里的引用类型
的概念去理解。
这一点与 CommonJS 规范完全不同。
CommonJS 模块输出的是值的缓存
,不存在动态更新。
// module1.js export var foo = 'bar'; setTimeout(() => foo = 'baz', 500);
// module2.js import {foo} from './module1.js' console.log(foo) setTimeout(() => console.log(foo), 1000); // console的结果 // bar // baz
2.3.2 export可以出现在模块内的任何位置,但不能处于块级作用域内
// 报错 { export let foo = 'bar'; }
2.3.3 import具有提升效果(类似于var),会提升到整个模块的头部,首先执行
console.log(foo) import {foo} from './script1.js'
参考资料:ECMAScript 6 入门
本文纯属原创,为了方便大家理解,小故事,小栗子都是笔者自己想的。如果您觉得对你有帮助,麻烦给个赞,给作者灰暗的生活挥洒挥洒积极向上的正能量,谢谢啦^_^。
相关推荐:
Atas ialah kandungan terperinci 什么是模块?深刻理解ES6模块. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian Pengenalan: Dengan perkembangan teknologi yang berterusan, teknologi pengecaman pertuturan telah menjadi bahagian penting dalam bidang kecerdasan buatan. Sistem pengecaman pertuturan dalam talian berdasarkan WebSocket dan JavaScript mempunyai ciri kependaman rendah, masa nyata dan platform merentas, dan telah menjadi penyelesaian yang digunakan secara meluas. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem pengecaman pertuturan dalam talian.

WebSocket dan JavaScript: Teknologi utama untuk merealisasikan sistem pemantauan masa nyata Pengenalan: Dengan perkembangan pesat teknologi Internet, sistem pemantauan masa nyata telah digunakan secara meluas dalam pelbagai bidang. Salah satu teknologi utama untuk mencapai pemantauan masa nyata ialah gabungan WebSocket dan JavaScript. Artikel ini akan memperkenalkan aplikasi WebSocket dan JavaScript dalam sistem pemantauan masa nyata, memberikan contoh kod dan menerangkan prinsip pelaksanaannya secara terperinci. 1. Teknologi WebSocket

Cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian Dalam era digital hari ini, semakin banyak perniagaan dan perkhidmatan perlu menyediakan fungsi tempahan dalam talian. Adalah penting untuk melaksanakan sistem tempahan dalam talian yang cekap dan masa nyata. Artikel ini akan memperkenalkan cara menggunakan WebSocket dan JavaScript untuk melaksanakan sistem tempahan dalam talian dan memberikan contoh kod khusus. 1. Apakah itu WebSocket? WebSocket ialah kaedah dupleks penuh pada sambungan TCP tunggal.

Pengenalan kepada cara menggunakan JavaScript dan WebSocket untuk melaksanakan sistem pesanan dalam talian masa nyata: Dengan populariti Internet dan kemajuan teknologi, semakin banyak restoran telah mula menyediakan perkhidmatan pesanan dalam talian. Untuk melaksanakan sistem pesanan dalam talian masa nyata, kami boleh menggunakan teknologi JavaScript dan WebSocket. WebSocket ialah protokol komunikasi dupleks penuh berdasarkan protokol TCP, yang boleh merealisasikan komunikasi dua hala masa nyata antara pelanggan dan pelayan. Dalam sistem pesanan dalam talian masa nyata, apabila pengguna memilih hidangan dan membuat pesanan

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

JavaScript dan WebSocket: Membina sistem ramalan cuaca masa nyata yang cekap Pengenalan: Hari ini, ketepatan ramalan cuaca sangat penting kepada kehidupan harian dan membuat keputusan. Apabila teknologi berkembang, kami boleh menyediakan ramalan cuaca yang lebih tepat dan boleh dipercayai dengan mendapatkan data cuaca dalam masa nyata. Dalam artikel ini, kita akan mempelajari cara menggunakan teknologi JavaScript dan WebSocket untuk membina sistem ramalan cuaca masa nyata yang cekap. Artikel ini akan menunjukkan proses pelaksanaan melalui contoh kod tertentu. Kami

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut

Penggunaan: Dalam JavaScript, kaedah insertBefore() digunakan untuk memasukkan nod baharu dalam pepohon DOM. Kaedah ini memerlukan dua parameter: nod baharu untuk dimasukkan dan nod rujukan (iaitu nod di mana nod baharu akan dimasukkan).
