[解決済み] RequireJS/AMDで循環依存性を処理する方法とは?
質問
私のシステムでは、いくつかのクラスがブラウザに読み込まれ、開発中はそれぞれ別のファイルであり、本番では一緒に結合されるようになっています。それらが読み込まれると、グローバル オブジェクトのプロパティが初期化されます。
G
この例のように。
var G = {};
G.Employee = function(name) {
this.name = name;
this.company = new G.Company(name + "'s own company");
};
G.Company = function(name) {
this.name = name;
this.employees = [];
};
G.Company.prototype.addEmployee = function(name) {
var employee = new G.Employee(name);
this.employees.push(employee);
employee.company = this;
};
var john = new G.Employee("John");
var bigCorp = new G.Company("Big Corp");
bigCorp.addEmployee("Mary");
独自のグローバルオブジェクトを使用する代わりに、各クラスを独自の AMDモジュール をベースにして James Burke の提案 :
define("Employee", ["Company"], function(Company) {
return function (name) {
this.name = name;
this.company = new Company(name + "'s own company");
};
});
define("Company", ["Employee"], function(Employee) {
function Company(name) {
this.name = name;
this.employees = [];
};
Company.prototype.addEmployee = function(name) {
var employee = new Employee(name);
this.employees.push(employee);
employee.company = this;
};
return Company;
});
define("main", ["Employee", "Company"], function (Employee, Company) {
var john = new Employee("John");
var bigCorp = new Company("Big Corp");
bigCorp.addEmployee("Mary");
});
問題は、以前は Employee と Company の間に宣言時の依存関係がなかったことです。つまり、好きな順序で宣言を配置することができましたが、現在 RequireJS を使用して、これは依存関係を導入し、ここでは(意図的に)循環しているので、上記のコードは失敗します。もちろん
addEmployee()
を追加すると、最初の行
var Employee = require("Employee");
は
を追加すると
しかし、この解決策は、RequireJS/AMDを使用しない場合よりも劣っていると私は考えています。
RequireJS/AMD でこの問題を解決する良い方法はありますか?それとも、私は RequireJS/AMD をそのために設計されていないもののために使っていますか?
どのように解決するのですか?
これは確かにAMD形式の制約です。エクスポートを使えば、この問題は解消されます。私はexportsは醜いと思っていますが、通常のCommonJSモジュールが問題を解決する方法です。
define("Employee", ["exports", "Company"], function(exports, Company) {
function Employee(name) {
this.name = name;
this.company = new Company.Company(name + "'s own company");
};
exports.Employee = Employee;
});
define("Company", ["exports", "Employee"], function(exports, Employee) {
function Company(name) {
this.name = name;
this.employees = [];
};
Company.prototype.addEmployee = function(name) {
var employee = new Employee.Employee(name);
this.employees.push(employee);
employee.company = this;
};
exports.Company = Company;
});
その他、メッセージにあるrequire("Employee")もうまくいくでしょう。
一般的に、モジュールでは、AMDであろうとなかろうと、循環的な依存関係をより認識する必要があります。プレーンなJavaScriptであっても、あなたの例のGオブジェクトのようなオブジェクトを確実に使用する必要があります。
関連
-
[解決済み] JavaScriptで要素のクラスを変更するにはどうすればよいですか?
-
[解決済み] jQueryでページを更新するにはどうすればよいですか?
-
[解決済み] JavaScriptでカンマを桁区切りにして数値を表示する方法
-
[解決済み] オブジェクトをメンバーとして、プレーンなJavaScriptオブジェクトをループさせる方法
-
[解決済み] CommonJSとAMDとRequireJSの関係?
-
[解決済み] URL/アドレスバーからJavascriptの関数を呼び出す
-
[解決済み] 文字列がhtmlであるかどうかをチェックする
-
[解決済み] JavaScriptでの大文字小文字を区別しない正規表現
-
[解決済み] CORS: 認証モードは 'include' です。
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScriptで次の要素/前の要素を取得しますか?
-
[解決済み] Google maps API V3 - 同一地点に複数のマーカーを設置する。
-
[解決済み] モバイルWeb HTML5フレームワークの選び方【終了しました
-
[解決済み] 文字列がhtmlであるかどうかをチェックする
-
[解決済み] Javascript の parseInt() で先頭のゼロを削除する。
-
[解決済み] なぜjavascriptのES6 Promisesはresolve後も実行を継続するのですか?
-
[解決済み] JavaScriptのArray.sort()メソッドでシャッフルするのは正しいのか?
-
[解決済み] V8 Javascript エンジンのスタンドアロン実行
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?
-
[解決済み] 変異を伴わないオブジェクトからの値の削除