ホームページ >ウェブフロントエンド >フロントエンドQ&A >フロントエンドモジュラーAMDとCMDの違いは何ですか?
違い: AMD と CMD は、依存モジュールの実行タイミングの処理が異なります。AMD は事前依存関係を推奨し、モジュールを定義するときに依存するモジュールを宣言します。CMD は、特定の場合にのみ近くの依存関係を推奨します。モジュールをインストールするときに必要になります。
JavaScript 開発の初期には、シンプルなページ操作ロジックをほんの数語で実装することが目的でしたが、現在では CPU とブラウザのパフォーマンスが大幅に向上しています。多くのページ ロジックがクライアントに移行されました (フォーム検証など)。Web2.0 時代の到来により、Ajax テクノロジが広く使用され、jQuery やその他のフロントエンド ライブラリが際限なく登場し、フロントエンドコードはますます拡張されています 現時点では、JavaScript は組み込みとして使用されています スクリプト言語の位置付けは揺らいでいますが、JavaScript はコードを整理するための明白な助けを提供しません クラスの概念さえありませんモジュールどころか、JavaScript の非常に単純なコード構成仕様では、このような大規模なコードを管理するには十分ではありません。 「このような大規模なコードは処理できません。他の言語が大規模なプログラミングを処理する方法から学ぶことができます。Java には、
パッケージという重要な概念があります。論理的に関連するコードは同じパッケージに編成されます。」パッケージは比較的独立した王国ですので、名前の衝突を心配する必要はありません。
import対応するパッケージimport java.util.ArrayList;
残念ながら、JavaScript は設計時の配置の関係で同様の機能を提供していません。開発者は、複雑な JavaScript コードを分離して整理するために、同様の機能をシミュレートする必要があります。これをモジュール性と呼びます。 モジュールは特定の機能を実装したファイルです。モジュールを使用すると、他の人のコードをより便利に使用したり、必要な機能に必要なモジュールをロードしたりできます。モジュール開発は一定の規範に従う必要があり、勝手なことをするとみんながめちゃくちゃになってしまいます
仕様策定のプロセスは苦痛ですフロントエンドの先駆者はスラッシュアンドの段階からスタートしましたこの段落を簡単に理解しましょう 特別な旅関数のカプセル化
関数について話したとき、私たちは関数の 1 つの機能は、特定のロジックを実装するためのステートメントのセットをパッケージ化することであると述べましたが、JavaScript のスコープは関数に基づいているため、モジュール化の最初のステップとして関数を使用するのは自然です。ファイルは最初のモジュールです。
function fn1(){ statement } function fn2(){ statement }
この方法では、必要に応じて、関数が配置されているファイル内の関数を呼び出すだけで済みます。
このアプローチの欠点は明らかです。グローバル変数を汚染し、変数名が他のモジュールと競合しないという保証はなく、モジュールのメンバー間に関係はありません。
Object
上記の問題を解決するために、すべてのモジュール メンバーを 1 つのオブジェクトにカプセル化できるオブジェクト記述方法が登場しました。
var myModule = { var1: 1, var2: 2, fn1: function(){ }, fn2: function(){ } }
この方法では、モジュールを呼び出したいときに対応するファイルを参照し、
myModule.fn2();
これにより、モジュール名が一意であり、同じモジュール内のメンバーも関連している限り、変数の汚染を回避できます
これは良い解決策のように見えますが、欠点もあります。外部メンバーは内部メンバーを自由に変更できますmyModel.var1 = 100;
これにより、予期しないセキュリティ上の問題が発生します
関数をすぐに実行することで、詳細を非表示にするという目的を達成できます
var myModule = (function(){ var var1 = 1; var var2 = 2; function fn1(){ } function fn2(){ } return { fn1: fn1, fn2: fn2 }; })();
このようにして、公開していない変数や関数をモジュールの外部で変更することはできません
上記のアプローチはモジュール化の基礎です。現在、一般的な JavaScript モジュール仕様には主に 2 つのタイプがあります:
CommonJSと AMD
CommonJS まず CommonJS について話しましょう Web ページにはモジュール式プログラミングがないため、ページの JavaScript ロジックだけが複雑ですが、それでも動作しますが、サーバー側にモジュールが必要です。したがって、JavaScript は長年にわたって Web 側で開発されてきましたが、最初に普及したモジュラー仕様はサーバーサイド JavaScript アプリケーションによってもたらされ、CommonJS 仕様は NodeJS に引き継がれ、これが JavaScript モジュラー プログラミングの正式な段階となります。 モジュールの定義
モジュール出力:
モジュールにはエクスポート
module.exports メソッドを使用してモジュールをロードします。このメソッドはファイルを読み取って実行し、ファイル内の
module.exports オブジェクトを返します
//模块定义 myModel.js var name = 'Byron'; function printName(){ console.log(name); } function printFullName(firstName){ console.log(firstName + name); } module.exports = { printName: printName, printFullName: printFullName } //加载模块 var nameModule = require('./myModel.js'); nameModule.printName();
実装が異なると、パスを要求する場合の要件が異なります。通常、
js 拡張子を省略したり、相対パスや絶対パスを使用したり、さらにはパスを使用したりすることもできます。パスを直接省略し、モジュール名を使用します (モジュールが組み込みシステム モジュールである場合)
仔细看上面的代码,会发现require
是同步的。模块系统需要同步读取模块文件内容,并编译执行以得到模块接口。
这在服务器端实现很简单,也很自然,然而, 想在浏览器端实现问题却很多。
浏览器端,加载JavaScript最佳、最容易的方式是在document中插入script
标签。但脚本标签天生异步,传统CommonJS模块在浏览器环境中无法正常加载。
解决思路之一是,开发一个服务器端组件,对模块代码作静态分析,将模块与它的依赖列表一起返回给浏览器端。 这很好使,但需要服务器安装额外的组件,并因此要调整一系列底层架构。
另一种解决思路是,用一套标准模板来封装模块定义,但是对于模块应该怎么定义和怎么加载,又产生的分歧:
AMD
AMD 即Asynchronous Module Definition
,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范
由于不是JavaScript原生支持,使用AMD规范进行页面开发需要用到对应的库函数,也就是大名鼎鼎RequireJS
,实际上AMD 是 RequireJS 在推广过程中对模块定义的规范化的产出
requireJS主要解决两个问题
看一个使用requireJS的例子
// 定义模块 myModule.js define(['dependency'], function(){ var name = 'Byron'; function printName(){ console.log(name); } return { printName: printName }; }); // 加载模块 require(['myModule'], function (my){ my.printName(); });
语法
requireJS定义了一个函数 define,它是全局变量,用来定义模块
define(id?, dependencies?, factory);
在页面上使用require
函数加载模块
require([dependencies], function(){});
require()函数接受两个参数
require()函数在加载依赖的函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。
CMD
CMD 即Common Module Definition
通用模块定义,CMD规范是国内发展出来的,就像AMD有个requireJS,CMD有个浏览器的实现SeaJS,SeaJS要解决的问题和requireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同
语法
Sea.js 推崇一个模块一个文件,遵循统一的写法
define
define(id?, deps?, factory)
因为CMD推崇
factory有三个参数
function(require, exports, module)
require
require 是 factory 函数的第一个参数
require(id)
require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口
exports
exports 是一个对象,用来向外提供模块接口
module
module 是一个对象,上面存储了与当前模块相关联的一些属性和方法
demo
// 定义模块 myModule.js define(function(require, exports, module) { var $ = require('jquery.js') $('p').addClass('active'); }); // 加载模块 seajs.use(['myModule.js'], function(my){ });
AMD与CMD区别
关于这两个的区别网上可以搜出一堆文章,简单总结一下
最明显的区别就是在模块定义时对依赖的处理不同
AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
CMD推崇就近依赖,只有在用到某个模块的时候再去require
这种区别各有优劣,只是语法上的差距,而且requireJS和SeaJS都支持对方的写法
AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机或者方式不同
requireJS は非同期読み込みモジュールであり、SeaJS は同期読み込みモジュールであると多くの人が言います。この理解は実際には不正確です。実際、読み込みモジュールはすべて非同期ですが、AMD はフロントエンドに依存しており、js は簡単にそれを知ることができます依存モジュールは誰ですか。すぐにロードされ、CMD は近くの依存関係に依存します。どのモジュールに依存しているかを知るには、モジュールを使用して文字列に変換し、再度解析する必要があります。これは多くの人が批判している点でもありますCMD. 開発の利便性をもたらすためにパフォーマンスを犠牲にしています。実際、モジュールの解析では無視できるほど時間が短いです。
なぜこの 2 つの違いは、依存するモジュールの実行タイミングの違いであると言えるのでしょうか? ADM は非同期で、CMD は同期であると多くの人が考えていますか (名前を除いて...)
モジュールも非同期でロードされます。AMD は、モジュールをロードした後に、変更されたモジュールを実行します。すべてのモジュールがロードされた後、実行されると、require コールバック関数に入り、メイン ロジックが実行されます。この効果はモジュールの実行順序に依存します。書き込み順序と一致しない場合があります。ネットワーク速度に応じて、どれが最初にダウンロードされ、どれがダウンロードされるかが決まります。 1 つが最初に実行されますが、メイン ロジックはすべての依存関係がロードされた後に実行する必要があります。
CMD は、特定の依存モジュールをロードした後は実行されません。ダウンロードされるだけです。すべての依存モジュールがロードされた後、メインロジック. 対応するモジュールは、require ステートメントが見つかった場合にのみ実行されます. このようにして、モジュールの実行順序と書き込み順序は完全に一貫しています.
これは、多くの人が AMD のユーザー エクスペリエンスであると言うことでもあります遅延がなく、依存モジュールが事前に実行されるため、優れています。ユーザーが必要な場合にのみ実行されるため、CMD のパフォーマンスが優れています。
プログラミング関連の知識の詳細については、こちらをご覧ください: プログラミング ビデオ# ##! !
以上がフロントエンドモジュラーAMDとCMDの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。