序文
JavaScriptの本来の意図:単純なページインタラクションロジックを実装すること、ほんの数語。
web2.0時代の到来とともに、Ajaxテクノロジーが広く使用され、jQueryなどのフロントエンドライブラリが無限のストリームで出現し、フロントエンドコードがますます拡張されています。
問題:
このとき、埋め込みスクリプト言語としてのJavaScriptの位置付けは揺らいでいましたが、クラスの概念がなくても、JavaScriptはコードを整理するための明白な助けにはなりませんでした。JavaScriptの非常に単純なコード編成仕様は、このような大規模なコード編成を制御するのに十分ではありませんでした。スケールコード。
1.モジュール
モジュール化:これは、複雑なシステムを、より合理的なコード構造とより高い保守性を備えた管理可能なモジュールに分解する方法です。
理想的な状態では、コアビジネスロジックコードの一部を完了するだけで済み、他の依存関係は、他の人が作成したモジュールを直接ロードすることで使用できます。
モジュールなし
<script src="jquery.js"></script>
<script src="jquery_scroller.js"></script>
<script src="main.js"></script>
<script src="other1.js"></script>
<script src="other2.js"></script>
<script src="other3.js"></script>
利点:
1つのjsファイルを使用する場合と比較して、複数のjsファイルを使用して最も単純なモジュール化を実現するというアイデアは改善されています。
短所:
グローバルスコープの汚染。すべてのモジュールはグローバルに公開されているため、単純に使用するとグローバル変数の名前の競合が発生します。もちろん、名前空間を使用してモジュールを解決することもできます。大規模なプロジェクトの場合、jsには多くの種類があり、開発者はモジュールとコードライブラリ間の依存関係を手動で解決する必要があり、その後のメンテナンスコストが高くなります。依存関係は明らかではなく、メンテナンスに役立ちません。たとえば、main.jsはjqueryを使用する必要がありますが、上記のファイルからはそれを確認できません。jqueryを忘れると、エラーが報告されます。
2、CommonJS
CommonJs はサーバー側モジュールの仕様であり、Node.jsはこの仕様を採用しています。
CommonJS仕様によれば、単一のファイルはモジュールです。ロードモジュールはrequireメソッドを使用します。このメソッドはファイルを読み取って実行し、最後にファイル内のexportsオブジェクトを返します。
var math = require('math');
math.add(2, 3);
2行目のmath.add(2、3)は、1行目のrequire( 'math')の後に実行されるため、math.jsがロードされるのを待つ必要があります。つまり、読み込み時間が長いと、アプリケーション全体がそこで停止して待機します。 同期されていること require
がわかります。
CommonJSのロードモジュールは同期的であるため、後続の操作はロードが完了した後にのみ実行できます。Node.jsが主にサーバープログラミングに使用されるように、ロードされたモジュールファイルは通常ローカルハードディスクにすでに存在するため、ロードが高速であり、非同期ロードの方法を考慮する必要がないため、CommonJS仕様はより多くなります。該当します。ただし、ブラウザ環境の場合、サーバーからモジュールをロードするには、非同期モードを採用する必要があります。つまり、AMDCMDソリューションがあります。
3、AMD
AMDはAsynchronousModule Definitionの略で、中国語の名前は非同期モジュール定義を意味します。ブラウザ側のモジュラー開発の仕様です
AMDもrequire()ステートメントを使用してモジュールをロードしますが、CommonJSとは異なり、次の2つのパラメーターが必要です。
require([module], callback);
最初のパラメーター[module]は配列であり、そのメンバーはロードされるモジュールです。2番目のパラメーターcallbackは、ロードが成功した後のコールバック関数です。前のコードをAMD形式に書き換えると、次のようになります。
require(['math'], function (math) {
math.add(2, 3);
});
math.add()は、数学モジュールの読み込みと同期されておらず、ブラウザーは中断されません。したがって、明らかに、AMDはブラウザ環境により適しています。現在、二つの主要なJavaScriptライブラリの実装は、AMDの仕様があるrequire.jsとcurl.js。
RequireJSを使用
AMDは、プロモーションプロセスにおけるRequireJSのモジュール定義の標準化された出力です。
AMDはモジュールを非同期でロードします。そのモジュールは、オブジェクト関数コンストラクター文字列JSONなどのさまざまなタイプのモジュールをサポートします。
//通过数组引入依赖 ,回调函数通过形参传入依赖
define(['Module1', ‘Module2’], function (Module1, Module2) {
function foo () {
/// someing
Module1.test();
}
return {foo: foo}
});
第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层的或者一个绝对的标识。
- 2番目のパラメーターであるdependenciesは、現在のモジュールが依存し、モジュールによって定義されているモジュール識別子の配列リテラルです。
- 3番目のパラメーターであるファクトリは、インスタンス化する必要のある関数またはオブジェクトです。
module1として識別されるモジュールを作成します。これは、require、export、およびbetaとして識別されるモジュールに依存します。
AMD仕様では、出力モジュールをCommonJS仕様と互換性があります。現時点では、defineメソッドは次のとおりです。
define(function (require, exports, module) {
var reqModule = require("./someModule");
requModule.test();
exports.asplode = function () {
//someing
}
});
优点:
ブラウザ環境でモジュールを非同期にロードするのに適しています。複数のモジュールを並行してロードできます。短所:
開発コストが増加し、オンデマンドでロードすることはできませんが、すべての依存関係を事前にロードする必要があります。
4、CMD
CMDは、プロモーションプロセスにおけるSeaJSのモジュール定義の標準化された出力です。
CMDとAMDの違いは次のとおりです。
1. AMDは依存モジュールに対して事前に実行され、CMDは後で実行されます。ただし、RequireJS 2.0以降、実行を遅らせるように変更されています(書き込み方法によっては、処理方法が渡されません)。
2. AMDは事前依存関係を尊重し(モジュールを定義するときに依存するモジュールを宣言します)、CMDは近くの依存関係を尊重します(特定のモジュールが使用されている場合にのみ必要です-オンデマンドでロードします)。
//AMD
define(['./a','./b'], function (a, b) {
//依赖一开始就写好
a.test();
b.test();
});
//CMD
define(function (requie, exports, module) {
//依赖可以就近书写
var a = require('./a');
a.test();
...
//软依赖
if (status) {
var b = requie('./b');
b.test();
}
});
3. AMDのAPIはデフォルトで複数の目的のためのものであり、CMDは単一の責任を厳密に区別して尊重します。例:AMDのrequireは、グローバルとローカルに分けられます。CMDにはグローバルな要件はありません。モジュールシステムのロードと起動を実現するために、seajs.use()が提供されています。CMDのすべてのAPIはシンプルで純粋です。
AMDは、プロモーションプロセスにおけるRequireJSのモジュール定義の標準化された出力であり、CMDは、プロモーションプロセスで広く認識されているSeaJSです。RequireJsはdojoローダーの作者であるJamesBurkeから来ており、SeaJsは国内のフロントエンドマスターであるYuBoから来ています。両者の違いは、YuBoが12年で言った:
RequireJSとSeaJSはどちらも非常に優れたモジュールローダーです。2つの違いは次のとおりです。
1. 两者定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。SeaJS 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 服务器端
2. 两者遵循的标准有差异。RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范。规范的不同,导致了两者API 的不同。SeaJS 更简洁优雅,更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
3. 两者社区理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。SeaJS 不强推,而采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
4. 两者代码质量有差异。RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug。
5. 两者对调试等的支持有差异。SeaJS 通过插件,可以实现 Fiddler 中自动映射的功能,还可以实现自动 combo 等功能,非常方便便捷。RequireJS无这方面的支持。
6. 两者的插件机制有差异。RequireJS 采取的是在源码中预留接口的形式,源码中留有为插件而写的代码。SeaJS 采取的插件机制则与 Node 的方式一致开放自身,让插件开发者可直接访问或修改,从而非常灵活,可以实现各种类型的插件。
利点:ブラウザ側でのモジュラーロードも実現されます。オンデマンドでロードでき、依存関係が近くにあります。
短所: SPMパッケージに依存しているため、モジュールのロードロジックに偏りがあります。
5つのES6モジュール
CommonJS
- 基本的なデータ型の場合、レプリケーションに属します。モジュールによってキャッシュされます。同時に、別のモジュールがモジュールによって出力された変数を再割り当てできます。
- 複雑なデータ型の場合、これは浅いコピーです。2つのモジュールによって参照されるオブジェクトは同じメモリ空間を指しているため、モジュールの値を変更すると、他のモジュールに影響します。
- モジュールがrequireコマンドでロードされると、モジュール全体のコードが実行されます。
- requireコマンドを使用して同じモジュールをロードすると、モジュールは再度実行されませんが、キャッシュ内の値がフェッチされます。つまり、CommonJSモジュールが何度ロードされても、最初にロードされたときに1回だけ実行され、後でロードされたときに、システムキャッシュがない限り、最初の実行の結果が返されます。手動でクリアされます。
- サイクリックロードの場合、ロード中の実行に属します。つまり、スクリプトコードは、必要なときにすべて実行されます。モジュールが「周期的にロード」されると、実行された部分のみが出力され、実行されていない部分は出力されません。
ES6モジュール
- ES6モジュールの値は[動的読み取り専用参照]に属しています。
- 読み取り専用の場合、つまり、インポートされた変数の値を変更することはできません。また、インポートされた変数は、基本データ型または複合データ型に関係なく、読み取り専用です。モジュールがインポートコマンドを検出すると、読み取り専用の参照を生成します。スクリプトが実際に実行されると、読み取り専用参照を使用して、ロードされたモジュールの値が取得されます。
- ダイナミクスの場合、元の値が変更され、インポートによってロードされた値も変更されます。基本データ型か複雑データ型か。
- ループをロードするとき、ES6モジュールは動的に参照されます。2つのモジュール間に参照がある限り、コードを実行できます。
参照: