現在、すべてのフレームワークはモジュール式であり、フロントエンドのJavaScriptも例外ではありません。各モジュールは特定の機能を担当し、モジュール間に相互依存性があります。質問は、JavaScriptに依存関係インジェクションを実装する方法です。 (JavaScriptの依存関係インジェクション、主要なフレームワークには対応する実装があり、実装のアイデアのみがここで学習されます)
次の要件:
既に定義されたサービスモジュールキー値コレクションがあると仮定し、FUNCは追加された新しいサービスであり、パラメーターリストはサービス依存関係です。
コードコピーは次のとおりです。
var Services = {ABC:123、def:456、ghi:789}; //一部のサービスが定義されていると仮定します
関数サービス(ABC、GHI){
this.write = function(){
console.log(ABC);
console.log(ghi);
}
}
function activitor(func){
var obj;
// 成し遂げる
OBJを返します。
}
解決:
いくつかのメカニズム(反射?)を介して、FUNCで定義されたパラメーターリストを取り出し、値を1つずつ割り当てます。次に、いくつかのメカニズム(activitor?)を介して、FUNCがインスタンス化されます。
解決:
1。FUNCのパラメーターリストを取得します。
パラメーターリストを取得する方法は?最初に思い浮かぶのは、反射メカニズムです。 JavaScriptには何か反映がありますか?そこにあるはずです。現時点ではeval(str)関数を使用する方法のみを知っていますが、パラメーターリストを取得するための関連する実装はないようです。 func.argumentsの定義を見てみましょう。このプロパティは、FUNCを呼び出し、パラメーターを渡す場合にのみ有効であり、ニーズを満たすことができません。
それでは、func.toString()の後に文字列を処理することでパラメーターリストを取得できますか?
試してみましょう:
コードコピーは次のとおりです。
関数getFuncParams(FUNC){
var matches = func.tostring()。match(/^function/s*[^/(]*/(/s*([^//)]*)/)/m);
if(matches && matches.length> 1)
return matches [1] .replace(// s*/、 '').split( '、');
戻る [];
};
ここでは、FUNCパラメーターリスト配列を取得します。
2。パラメーターリストに基づいて依存関係を見つけます。
パラメーターリストを取得した後、つまり、依存関係リストが取得されます。依存関係をパラメーターとして渡すことは非常に簡単です。
コードコピーは次のとおりです。
var params = getfuncparams(func);
for(var i in params){
params [i] = services [params [i]];
}
3。依存関係パラメーターを渡してインスタンス化します。
JavaScriptにはfunc.constructorがあり、2つの関数があります:call(thisarg、[arg [、arg、[…]]]])を適用し(thisarg、args…)、インスタンス化func操作を実装できます。コール関数の最初のパラメーターはこのポインターであり、残りはパラメーターリストです。これは、FUNCパラメーターリストが既知であり、私のニーズを満たすことができない場合に使用するのに適しています。 2番目の適用関数を見てみましょう。最初のパラメーターもこのポインターであり、2番目のパラメーターはパラメーター配列です。呼び出されると、FUNCパラメーターリストに値を1つずつ自動的に割り当てます。これは私のニーズを満たしています。
コードはほぼ次のとおりです。
コードコピーは次のとおりです。
function activitor(func){
var obj = {};
func.apply(obj、params);
OBJを返します。
}
この時点で、このFUNCのインスタンスを作成し、このFUNCに必要なパラメーターを渡すことができます。
4。印刷してテストします:
完全なコード:
コードコピーは次のとおりです。
var
//一部のサービスが定義されていると仮定します
services = {ABC:123、def:456、ghi:789}、
// funcのパラメーターリストを取得します(依存関係リスト)
getFuncParams = function(func){
var matches = func.tostring()。match(/^function/s*[^/(]*/(/s*([^//)]*)/)/m);
if(matches && matches.length> 1)
return matches [1] .replace(// s+/、 '').split( '、');
戻る [];
}、
//パラメーターリスト(依存関係)に従ってパラメーター(依存関係)を入力します
setFuncParams = function(params){
for(var i in params){
params [i] = services [params [i]];
}
パラメージを返します。
};
//アクティベーター
function activitor(func){
var obj = {};
func.apply(obj、setfuncparams(getfuncparams(func)));
OBJを返します。
}
//新しいサービスを定義します
関数サービス(ABC、GHI){
this.write = function(){
console.log(ABC);
console.log(ghi);
}
}
//サービスをインスタンス化してメソッドを呼び出します
var service = activator(service);
service.write();
コンソールが正常に印刷されました!