Heutzutage wird jedes Framework modularisiert, selbst Front-End-Javascript ist keine Ausnahme. Jedes Modul ist für bestimmte Funktionen verantwortlich und es gibt Abhängigkeiten zwischen den Modulen. Es stellt sich also die Frage: Wie implementiert man die Abhängigkeitsinjektion in JavaScript? (Javascript-Abhängigkeitsinjektion, alle wichtigen Frameworks haben entsprechende Implementierungen, hier lernen wir nur die Implementierungsideen)
Die folgenden Anforderungen:
Angenommen, es gibt bereits eine definierte Servicemodul-Schlüsselwertsammlung. func Für einen neu hinzugefügten Dienst enthält die Parameterliste die Dienstabhängigkeiten.
var services = { abc : 123, def : 456, ghi : 789 }; // Angenommen, dass ein Dienst definiert wurde
function Service(abc, ghi){ this.write = function(){ console.log(abc); console.log(ghi); } } function Activitor(func){ var obj; // 实现 return obj; }
Lösung:
Verwenden Sie einen Mechanismus (Reflexion?), um die durch die Funktion definierte Parameterliste herauszunehmen und Werte nacheinander zuzuweisen. Dann instanziieren Sie die Funktion durch einen Mechanismus (Aktivator?).
Lösung:
1. Holen Sie sich die Parameterliste der Funktion:
Wie bekomme ich die Parameterliste? Das erste, was mir in den Sinn kommt, ist der Reflexionsmechanismus. Gibt es also eine Reflexion in Javascript? Derzeit weiß ich nur, wie man die Funktion eval(str) verwendet, aber es scheint, dass es keine relevante Implementierung zum Abrufen der Parameterliste gibt. Wenn Sie sich die Definition von func.arguments noch einmal ansehen, ist diese Eigenschaft nur gültig, wenn func aufgerufen und Parameter übergeben werden, und kann die Anforderungen nicht erfüllen.
Können wir die Parameterliste erhalten, indem wir den String nach func.toString() verarbeiten?
Lass es uns ausprobieren:
function getFuncParams(func) { var matches = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m); if (matches && matches.length > 1) return matches[1].replace(/\s*/, '').split(','); return []; };
Jetzt erhalten Sie das Funktionsparameterlisten-Array.
2. Suchen Sie Abhängigkeiten basierend auf der Parameterliste:
Nachdem Sie die Parameterliste, also die Abhängigkeitsliste, erhalten haben, ist es sehr einfach, die Abhängigkeiten als Parameter zu übergeben .
var params = getFuncParams(func); for (var i in params) { params[i] = services[params[i]]; }
3. Abhängigkeitsparameter übergeben und instanziieren:
Wir wissen, dass es func.constructor in Javascript und call(thisArg,[arg[,arg , [arg,[…]]]]) und apply(thisArg,args…) können beide Funktionen die Instanziierungsfunktionsoperation implementieren. Der erste Parameter der Aufruffunktion ist dieser Zeiger, der Rest ist die Parameterliste. Dies eignet sich zur Verwendung, wenn die Funktionsparameterliste bekannt ist, aber nicht meinen Anforderungen entspricht. Wenn Sie sich die zweite Apply-Funktion ansehen, ist der erste Parameter auch dieser Zeiger und der zweite Parameter das Parameter-Array. Wenn er aufgerufen wird, weist er der Parameterliste von func automatisch nacheinander Werte zu, die genau meinen Anforderungen entsprechen Bedürfnisse.
Der Code sieht ungefähr wie folgt aus:
function Activitor(func){ var obj = {}; func.apply(obj, params); return obj; }
An diesem Punkt können wir eine Instanz der Funktion erstellen und die für die Funktion erforderlichen Parameter übergeben.
4. Drucken und testen:
Vollständiger Code:
var // 假设已定义好某些Service 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(','); return []; }, // 根据参数列表(依赖列表)填充参数(依赖项) setFuncParams = function (params) { for (var i in params) { params[i] = services[params[i]]; } return params; }; // 激活器 function Activitor(func) { var obj = {}; func.apply(obj, setFuncParams(getFuncParams(func))); return obj; } // 定义新Service function Service(abc, ghi) { this.write = function () { console.log(abc); console.log(ghi); } } // 实例化Service并调用方法 var service = Activitor(Service); service.write();
Die Konsole wird erfolgreich gedruckt!