Friends who have played FPS games should know that a fully assembled M4 rifle usually consists of body, silencer, magnifier, grip, and stock
.
If the M4 rifle is regarded as a page, then we can make the following analogy Gun body-> <main></main>
Muffler-> <header></header>
Mirror-> <nav></nav>
Grip -> <aside></aside>
Butt-> <footer></footer>
OK, you just did it One thing is to split the m4 rifle into five parts. Each part you split is a module [module], and the process of splitting it is Modularization【modularization】.
Modularization is a programming idea. Its core is to split tasks and simplify complex problems. In this way, it not only facilitates the division of labor and collaboration among many people, but also helps us Quickly locate problems
#Facilitates division of labor and collaboration among multiple people - Different people can develop different modules and then combine them to greatly increase team efficiency
Help us quickly locate the problem - if the recoil is too large, then 80% of it is a problem with the gun stock or grip; if the sound is too loud, then 80% of it is a problem with the silencer.
The following is a small chestnut to talk about the development history of modularization
Mr. Gong and Mr. Sheng took the I have a project, and they need to implement some functions separately. It is very simple, that is, Console comes out with their own variables a
. So the two of them put it together and arranged for Mr. Gong’s code to be placed separately in Written in script1.js
, Mr. Sheng’s code was written separately in script2.js
, and then imported separately using script tags
// 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>
Soon they encountered the first problem —— Variable naming conflict
Especially when asynchronous is included, the following situation will occur
// script1.js文件 var a = 1 setTimeout(()=>{ console.log(a) // 我们想console出来1,却console出了2 },1000)
// script2.js文件 var a = 2 console.log(a)
The above problem is obviously due to a A global variable causes , so the solution is also very clear - Create a local variable
In the ES5 era, use immediate execution functions to create local Variable
// script1.js文件 !function(){ var a = 1 setTimeout(()=>{ console.log(a) // 这下是2了 },1000) }() // 下面有5000行代码
// script2.js文件 console.log(2)
In the ES6 era, block-level scope let
// script1.js文件 { let a = 1 setTimeout(()=>{ console.log(a) // 这下是2了 },1000) }
// script2.js文件 { let a = 2 console.log(a) }
Later, the company hired a front-end boss, He said that he could only control the console variable now, so he created a new control.js
file
and connected script1.js and scirpt2.js through the window object
// 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()
At this time, a very important point is that window is a global variable and acts as a public warehouse. This warehouse has two key functions,storage [Export]
andGet [Dependency]
// 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()
The annoying product has changed its requirements and given a name.js File
// name.js文件 window.names = ['gongxiansheng','pengxiansheng']
requires that Mr. Gong and Mr. Sheng now need the Console to reveal their names
Isn’t this simple? It took a few seconds to write
// 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>
, but they soon discovered that all that came out of the console were undefined
The front-end boss saw the problem at a glance and said to the two of themThe code you depend on must be introduced before your own code, otherwise the value will not be obtained; see if my control.js is introduced after your code, because I used your code Oh yeah
Oh, it turns out to be a js file loading order problem, please change it
<!--HTML文件--> <script src="./name.js"></script> <script src="./script1.js"></script> <script src="./script2.js"></script> <script src="./control.js"></script>
But when there are more people, we will not be able to figure out who is relying on it. Who, to be on the safe side can only load them all, wasting too much performance
, the front-end boss shook his head and sighed
Variable conflict
To use window to connect each module
All dependencies need to be loaded
Also pay attention to the loading order
Modularity is one of the biggest highlights of ES6, because in the syntax before ES6 has never There was a modular system,which formed a huge obstacle to the development of large and complex projects. Because we cannot split the project, we cannot better carry out multi-person collaborative development. More importantly, Most other languages support modularity.
Since the language does not support it, how to introduce modularization into JS?
The front-end community has developed some module loading schemes of its own - this is also the origin of CommonJS [server] and AMD and CMD [browser].
但是现在ES6引入了模块化的功能,实现起来非常简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
import和export语法较为简单,大家去MDN可以看非常详细的讲解,笔者在这里知识用注释简单介绍一下
// 命名导出 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 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); // 异步的导入
// 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内的代码当做模块来对待-->
其实就是按照数据类型里的引用类型
的概念去理解。
这一点与 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
// 报错 { export let foo = 'bar'; }
console.log(foo) import {foo} from './script1.js'
参考资料:ECMAScript 6 入门
本文纯属原创,为了方便大家理解,小故事,小栗子都是笔者自己想的。如果您觉得对你有帮助,麻烦给个赞,给作者灰暗的生活挥洒挥洒积极向上的正能量,谢谢啦^_^。
相关推荐:
The above is the detailed content of What is a module? Deep understanding of ES6 modules. For more information, please follow other related articles on the PHP Chinese website!