Heim  >  Artikel  >  Web-Frontend  >  Was ist ein Modul? Tiefes Verständnis der ES6-Module

Was ist ein Modul? Tiefes Verständnis der ES6-Module

php是最好的语言
php是最好的语言Original
2018-08-09 16:13:122239Durchsuche

1. Modul

1.1 Was ist ein Modul? Was ist Modularität?

Freunde, die FPS-Spiele gespielt haben, sollten wissen, dass ein komplett zusammengebautes M4-Gewehr normalerweise 枪身+消音器+倍镜+握把+枪托 ist.

Wenn das M4-Gewehr als Seite betrachtet wird, dann können wir die folgende Analogie ziehen
枪身 -> <main></main>
消音器 -> <header></header>
倍镜 -> <nav></nav>
握把 -> <aside></aside>
枪托 -> <footer></footer>

OK, Sie haben gerade etwas getan, nämlich das M4-Gewehr in fünf Teile zu zerlegen , und jedes Teil, das Sie teilen, ist ein Modul [Modul] , der Prozess, den Sie aufteilen, ist Modularisierung [Modularisierung] .

Modularisierung ist eine Programmieridee, deren Kern darin besteht, Aufgaben aufzuteilen und komplexe Probleme zu vereinfachen , auf diese Weise 既方便多人分工协作,又可以帮助我们迅速定位问题

  • Bequem für Arbeitsteilung und Zusammenarbeit mit mehreren Personen – verschiedene Personen können verschiedene Module entwickeln und diese dann kombinieren, um die Teameffizienz erheblich zu steigern

  • Helfen Sie uns, das Problem schnell zu lokalisieren – in 80 % der Fälle Wenn der Rückstoß zu groß ist, liegt wahrscheinlich ein Problem mit dem Schalldämpfer vor.

1.2 Die blutige Geschichte der Modularisierung

Das Folgende ist eine kleine Kastanie, um über die Entwicklungsgeschichte der Modularisierung zu sprechen

Mr. Sheng nahm das Ich habe ein Projekt und sie müssen einige Funktionen separat implementieren. Es ist nur sehr einfach. Console kommt mit einer eigenen Variablen a heraus

Also haben die beiden es ausgedrückt zusammen und sorgten dafür, dass der Code von Herrn Gong separat in script1.js platziert wurde. Der Code von Herrn Sheng wurde separat in script2.js geschrieben und dann separat mit Skript-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>

eingeführt. Bald stießen sie auf das erste Problem – 变量命名冲突
insbesondere enthalten Wenn asynchron verwendet wird, tritt die folgende Situation auf

// script1.js文件

var a = 1
setTimeout(()=>{
  console.log(a)  // 我们想console出来1,却console出了2
},1000)
// script2.js文件

var a = 2
console.log(a)

Das obige Problem wird offensichtlich dadurch verursacht, dass a eine globale Variable ist, Daher ist die Lösung auch sehr klar: 造一个局部变量呗

Lokale Variablen

Die ES5-Ära verwendet Funktionen zur sofortigen Ausführung, um lokale Variablen zu erstellen
// script1.js文件
!function(){
    var a = 1
    setTimeout(()=>{
      console.log(a)  // 这下是2了
    },1000)
}()
// 下面有5000行代码
// script2.js文件

console.log(2)
Die ES6-Ära verwendet direkt 块级作用域+let
// script1.js文件
{
    let a = 1
    setTimeout(()=>{
      console.log(a)  // 这下是2了
    },1000)
}
// script2.js文件
{
    let a = 2
    console.log(a)
}

Verbinden Sie jedes Modul über ein Fenster

Später stellte das Unternehmen einen Front-End-Chef ein und sagte, dass er jetzt nur noch steuern könne, wann Variablen konsoliert werden sollen, also erstellte er ein neues control.js Datei
und über die Fensterobjekte script1.js und scirpt2.js verbunden

// 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()
Zu diesem Zeitpunkt ist ein sehr wichtiger Punkt, dass window eine globale Variable ist und fungiert als öffentliches Lager. Das Lager hat zwei Schlüsselfunktionen: 存【导出】 und 取【依赖】
// script1.js文件
{
    let a = 1
    // 把这个函数存放进window,就是导出到window
    window.module1 = function() {
        console.log(a)
    }
}
rrree

Hängt von der Reihenfolge der Beladung ab

Das lästige Produkt hat seine Anforderungen geändert und eine name.js-Datei erhalten

// control.js文件
setTimeout(()=>{
    // 我们从window里取出module1函数进行调用,就是依赖了script1.js文件
    window.module1()
},1000)

window.module2()

Fordern Sie, dass Herr Gong und Herr Sheng jetzt die Konsole benötigen, um ihre Namen preiszugeben
Ist das nicht einfach? Es dauerte ein paar Sekunden, es zu schreiben

// name.js文件
window.names = [&#39;gongxiansheng&#39;,&#39;pengxiansheng&#39;]
// 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()

Aber bald stellten sie fest, dass alles, was aus der Konsole kam,undefined
Der Front-End-Chef sah das Problem auf einen Blick und sagte es ihnen
你们依赖的代码一定要在你们自己的代码前引入,不然是取不到值的;你看我的control.js是不是在你们俩的代码后面引入的,因为我用到了你们俩的代码了呀
Oh, es stellt sich heraus, dass es ein Problem mit der Ladereihenfolge von js-Dateien ist, bitte ändern Sie es

<!--HTML文件-->

<script src="./script1.js"></script>
<script src="./script2.js"></script>

但是在人多了以后,我们到时候会搞不清楚到底谁依赖了谁,保险起见只能全部都加载,性能浪费了太多, der Front-End-Chef schüttelte den Kopf und seufzte

2. ES6-Module

2.1 Die Schwachstellen der Modularisierung vor ES6

  1. Variablenkonflikte

  2. Sie Sie müssen Windows verwenden, um verschiedene Module zu verbinden

  3. Alle Abhängigkeiten müssen geladen werden

  4. Sie müssen auch auf die Ladereihenfolge achten

Modularisierung ist eines der größten Highlights von ES6, denn vor ES6 gab es noch nie ein modulares System in der Grammatik , was ein großes Hindernis für die Entwicklung von darstellte große und komplexe Projekte . Da wir das Projekt nicht aufteilen können, können wir die gemeinsame Entwicklung mehrerer Personen nicht besser durchführen. Noch wichtiger ist, dass die meisten anderen Sprachen Modularität unterstützen.

Da die Sprache dies nicht unterstützt, wie kann man Modularität in JS einführen?
Die Front-End-Community hat einige eigene Modulladepläne entwickelt – dies ist auch der Ursprung von CommonJS [Server] und AMD und CMD [Browser].


Was ist ein Modul? Tiefes Verständnis der ES6-Module

但是现在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 = [&#39;gongxiansheng&#39;,&#39;pengxiansheng&#39;]
export default names
// script1.js
import names from &#39;./name.js&#39;

let module1 = function () {
  console.log(names[0])
}
export default module1
// script2.js
import names from &#39;./name.js&#39;

let module2 = function() {
  console.log(names[1])
}
export default module2
// control.js
import module1 from &#39;./script1.js&#39;
import module2 from &#39;./script2.js&#39;

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 = &#39;bar&#39;;
setTimeout(() => foo = &#39;baz&#39;, 500);
// module2.js
import {foo} from &#39;./module1.js&#39;
console.log(foo)
setTimeout(() => console.log(foo), 1000);

// console的结果
// bar
// baz

2.3.2 export可以出现在模块内的任何位置,但不能处于块级作用域内

// 报错
{
  export let foo = &#39;bar&#39;;
}

2.3.3 import具有提升效果(类似于var),会提升到整个模块的头部,首先执行

console.log(foo)
import {foo} from &#39;./script1.js&#39;
参考资料:ECMAScript 6 入门
本文纯属原创,为了方便大家理解,小故事,小栗子都是笔者自己想的。如果您觉得对你有帮助,麻烦给个赞,给作者灰暗的生活挥洒挥洒积极向上的正能量,谢谢啦^_^。

相关推荐:

彻底搞懂JS无缝滚动代码

彻底弄懂CSS盒子模式(DIV布局)

Das obige ist der detaillierte Inhalt vonWas ist ein Modul? Tiefes Verständnis der ES6-Module. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn