Heim  >  Artikel  >  Web-Frontend  >  Vertieftes Verständnis der Modularisierung von JavaScript

Vertieftes Verständnis der Modularisierung von JavaScript

黄舟
黄舟Original
2017-03-24 14:56:281345Durchsuche

Modularisierung ist in einem Projekt sehr wichtig. Ein komplexes Projekt muss viele ähnliche Funktionsmodule haben. Wenn Sie die Module jedes Mal neu schreiben müssen, ist dies definitiv zeitaufwändig und arbeitsintensiv. Die Voraussetzung für das Zitieren anderer zum Schreiben von Modulen ist jedoch eine einheitliche „Eröffnungshaltung“. Wenn jeder seine eigene Schreibweise hat, wird es definitiv chaotisch sein. Hier sind mehrere JS-Modulspezifikationen.

Modularisierung ist in einem Projekt sehr wichtig. Wenn Sie die Module jedes Mal neu schreiben müssen, ist dies auf jeden Fall zeitaufwändig und arbeitsintensiv. Die Voraussetzung für das Zitieren anderer zum Schreiben von Modulen ist jedoch eine einheitliche „Eröffnungshaltung“. Wenn jeder seine eigene Schreibweise hat, wird es definitiv chaotisch sein. Hier sind mehrere JS-Modulspezifikationen.

1: Modularisierungsprozess eins: Skript-Tag

Dies ist die originellste JavaScript-Methode zum Laden von Dateien Modul, dann werden ihre Schnittstellen normalerweise im globalen Bereich verfügbar gemacht, dh im Fenster Objekt . Die Schnittstellenaufrufe verschiedener Module werden alle im gleichen Bereich verwendet 🎜>Namespace wird verwendet, um die Schnittstellen dieser Module zu organisieren.

Nachteile:

1. Verschmutzung des globalen Geltungsbereichs

2. Entwickler müssen das Problem von Modulen und Code subjektiv lösen Bibliotheksabhängigkeiten

3. Dateien können nur in der Reihenfolge geladen werden, in der Skript-Tags geschrieben werden

4 Verschiedene Ressourcen sind in großen Projekten schwer zu verwalten und führen zu langfristigen Problemen eine chaotische Codebasis

Zweitens: Modularisierungsprozess zwei: CommonJS-Spezifikation

Die Kernidee dieser Spezifikation besteht darin, Modulen das synchrone Laden anderer Module zu ermöglichen, von denen sie abhängig sind über die Methode

require und exportieren Sie dann die Schnittstellen, die verfügbar gemacht werden müssen, über exports oder module.exports.

require("module");
require("../file.js");
exports.doStuff = function(){};
module.exports = someValue;

Vorteile:

Einfach und benutzerfreundlich

2 zur Wiederverwendung

Nachteile:

1. Die synchrone Modullademethode ist in der Browserumgebung nicht geeignet Ressourcen sind asynchron. Geladen

2. Mehrere Module können nicht blockierend parallel geladen werden

Der Unterschied zwischen module.exports und exports

1. exports ist ein Verweis auf module.exports

2. Der Anfangswert von module.exports ist ein leeres Objekt {}, daher ist der Anfangswert von exports auch {}

3. require() gibt „module.exports“ anstelle von „exports“ zurück

Exportbeispiel:

// app.js
var circle = require('./circle');
console.log(circle.area(4));
// circle.js
exports.area = function(r){
 return r * r * Math.PI;
}
module.exports-Beispiel:

// app.js
var area = require('./area');
console.log(area(4));
// area.js
module.exports = function(r){
 return r * r * Math.PI;
}
Fehlerfall:

// app.js
var area = require('./area');
console.log(area(4));
// area.js
exports = function(r){
 return r * r * Math.PI;
}
überschreibt tatsächlich Exporte, was bedeutet, dass Exporte auf einen neuen Speicher verweisen (der Inhalt ist eine

Funktion , die die Fläche eines Kreises berechnet), Dies bedeutet, dass Exporte und Module.Exports nicht mehr auf dasselbe verweisen Ein Stück Speicher, das heißt, Exporte und Module.Exports haben zu diesem Zeitpunkt keine Verbindung, das heißt, der Speicher, auf den Module.Exports zeigt, hat wurde in keiner Weise geändert und ist immer noch ein leeres Objekt {}, was bedeutet, dass „area.js“ exportiert wird. Ein leeres Objekt. Wenn wir also „area(4)“ in app.js aufrufen, entsteht ein TypeError: object ist keine Funktion, es wird ein Fehler gemeldet.

Zusammenfassung: Wenn das Modul ein Objekt exportieren soll, können sowohl Exports als auch module.exports verwendet werden (Exporte können jedoch nicht als neue überschrieben werden). Objekt) und wenn wir Nicht-Objektschnittstellen exportieren möchten, müssen und können wir nur module.exports überschreiben.

Drei: Modularisierungsprozess Drei: AMD-Spezifikation

Da die browserseitigen Module nicht synchron geladen werden können, wirkt sich dies auf das Laden und Ausführen nachfolgender Module aus, so AMD (Die Spezifikation Asyn

chronous Module Definition (Asynchronous Module Definition) war geboren.

Die folgenden zwei APIs sind im AMD-Standard definiert

1. require([module], callback);

2 🎜 >
Die Require-Schnittstelle wird verwendet, um eine Reihe von Modulen zu laden, und die Define-Schnittstelle wird verwendet, um ein Modul zu definieren und verfügbar zu machen.

Beispiel:

define("module", ["dep1", "dep2"], function(d1, d2){
 return someExportedValue;
});
require(["module", "../file"], function(module, file){ /* ... */ });

Vorteile: 1. Geeignet für das asynchrone Laden von Modulen in einer Browserumgebung

2. Mehrere Module können parallel geladen werden

Nachteile: 1 Es ist schwieriger und die Semantik der Moduldefinitionsmethode ist nicht glatt

2. Es entspricht nicht der allgemeinen modularen Denkweise und ist eine kompromittierte Implementierung

Viertens: Modularisierungsprozess vier: CMD-Spezifikation

CMD(Common Module Definition)规范和AMD很相似,尽量保持简单,并与CommonJS和Node.js的 Modules 规范保持了很大的兼容性。在CMD规范中,一个模块就是一个文件。

示例:

define(function(require, exports, module){
 var $ = require('jquery');
 var Spinning = require('./spinning');
 exports.doSomething = ...
 module.exports = ...
})

优点:

1、依赖就近,延迟执行

2、可以很容易在 Node.js 中运行

缺点:

1、依赖 SPM 打包,模块的加载逻辑偏重

AMD和CMD的区别

AMD和CMD起来很相似,但是还是有一些细微的差别,让我们来看一下他们的区别在哪里:

1、对于依赖的模块,AMD是提前执行,CMD是延迟执行。

2、AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require。看代码:

// AMD
define(['./a', './b'], function(a, b){ // 依赖必须一开始就写好
  a.doSomething()  
  // 此处略去 100 行
  b.doSomething()  
  ...
});
// CMD
define(function(require, exports, module){
  var a = require('./a')  
  a.doSomething()  
  // 此处略去 100 行
  var b = require('./b')
  // 依赖可以就近书写
  b.doSomething()
  // ...
});

3、AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。

五:模块化进程五:ES6模块化

EcmaScript6标准增加了JavaScript语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS和AMD模块,都只能在运行时确定这些东西。

在 ES6 中,我们使用export关键字来导出模块,使用import关键字引用模块。需要说明的是,ES6的这套标准和目前的标准没有直接关系,目前也很少有JS引擎能直接支持。因此Babel的做法实际上是将不被支持的import翻译成目前已被支持的require。

尽管目前使用import和require的区别不大(本质上是一回事),但依然强烈推荐使用import关键字,因为一旦JS引擎能够解析ES6的import关键字,整个实现方式就会和目前发生比较大的变化。如果目前就开始使用import关键字,将来代码的改动会非常小。

示例:

import "jquery";
export functiondoStuff(){}
module "localModule" {}

优点:

1、容易进行静态分析

2、面向未来的 EcmaScript 标准

缺点:

1、原生浏览器端还没有实现该标准

2、全新的命令字,新版的 Node.js才支持

Das obige ist der detaillierte Inhalt vonVertieftes Verständnis der Modularisierung von JavaScript. 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