Inhaltsverzeichnis
Zielsetzung
erfordernjs/AMD-Methode" >erfordernjs/AMD-Methode
反射(reflection)方法
结语
Heim Web-Frontend js-Tutorial Detaillierte Analyse des Beispielcodes für die Abhängigkeitsinjektion in JavaScript

Detaillierte Analyse des Beispielcodes für die Abhängigkeitsinjektion in JavaScript

Mar 14, 2017 pm 03:18 PM

Die Welt der

ComputerProgrammierung ist eigentlich ein Prozess, bei dem einfache Teile ständig abstrahiert und diese Abstraktionen organisiert werden. JavaScript ist keine Ausnahme. Wenn wir JavaScript zum Schreiben von Anwendungen verwenden, verwenden wir alle Codes, die von anderen geschrieben wurden, beispielsweise einige berühmte Open-Source-Bibliotheken oder Frameworks. Da unser Projekt wächst, werden immer mehr Module, auf die wir uns verlassen müssen, immer wichtiger. Derzeit ist die effektive Organisation dieser Module zu einem sehr wichtigen Thema geworden. Abhängigkeitsinjektion löst das Problem, wie codeabhängige Module effektiv organisiert werden können. Möglicherweise haben Sie den Begriff „Abhängigkeitsinjektion“ in einigen Frameworks oder Bibliotheken gehört, beispielsweise im berühmten Front-End-FrameworkAngularJS, wo die Abhängigkeitsinjektion eine der sehr wichtigen Funktionen ist. Allerdings ist die Abhängigkeitsinjektion überhaupt nichts Neues. In anderen Programmiersprachen wie PHP gibt es sie schon seit langem. Gleichzeitig ist die Abhängigkeitsinjektion nicht so kompliziert wie gedacht. In diesem Artikel lernen wir das Konzept der Abhängigkeitsinjektion in JavaScript kennen und erklären auf einfache und unkomplizierte Weise, wie man Code im „Abhängigkeitsinjektionsstil“ schreibt.

Zielsetzung

Angenommen, wir haben jetzt zwei Module. Das erste Modul wird zum Senden von Ajax-Anfragen verwendet, während das zweite Modul als Router verwendet wird.

var service = function() {
    return { name: 'Service' };
}
var router = function() {
    return { name: 'Router' };
}
Nach dem Login kopieren

Zu diesem Zeitpunkt haben wir eine Funktion geschrieben, die die Verwendung der beiden oben genannten Module erfordert:

var doSomething = function(other) {
    var s = service();
    var r = router();
};
Nach dem Login kopieren

Hier, für uns Der Code wird etwas interessanter, dieser Parameter muss noch ein paar Parameter erhalten. Natürlich können wir den obigen Code vollständig verwenden, aber der obige Code ist in jeder Hinsicht etwas weniger flexibel. Wenn der Modulname, den wir verwenden müssen, zu Service<a href="http://www.php.cn/wiki/1527.html" target="_blank">XML<code>Service<a href="http://www.php.cn/wiki/1527.html" target="_blank">XML</a> oder < wird code>DienstJSONService<a href="http://www.php.cn/wiki/1488.html" target="_blank">JSON</a>Was soll ich tun? Oder was wäre, wenn wir einige gefälschte Module zu Testzwecken verwenden möchten? An dieser Stelle können wir nicht einfach die Funktion selbst bearbeiten. Als erstes müssen wir also die abhängigen Module als Parameter an die Funktion übergeben. Der Code lautet wie folgt:

Im obigen Code übergeben wir genau die Module, die wir benötigen. Aber das wirft ein neues Problem auf. Angenommen, wir rufen die Methode doSomething in beiden Teilen des Codes auf. Was ist, wenn wir an diesem Punkt eine dritte Abhängigkeit benötigen? Zu diesem Zeitpunkt ist es keine kluge Idee, den gesamten Funktionsaufrufcode zu bearbeiten. Daher benötigen wir einen Code, der uns dabei hilft. Dies ist das Problem, das der Abhängigkeitsinjektor zu lösen versucht. Jetzt können wir unsere Ziele festlegen:

erfordernjs/AMD-Methode

Vielleicht haben Sie von den berühmten Requirejs gehört, einer Bibliothek, die Abhängigkeitsinjektionsprobleme sehr gut lösen kann:

define([&#39;service&#39;, &#39;router&#39;], function(service, router) {       
    // ...
});
Nach dem Login kopieren

Die Idee von Requirejs ist dass wir zuerst die erforderlichen Module beschreiben und dann Ihre eigenen Funktionen schreiben sollten. Dabei ist die Reihenfolge der Parameter wichtig. Angenommen, wir müssen ein Modul namens injector schreiben, das eine ähnliche Syntax implementiert.

var doSomething = injector.resolve([&#39;service&#39;, &#39;router&#39;], function(service, router, other) {
    expect(service().name).to.be(&#39;Service&#39;);
    expect(router().name).to.be(&#39;Router&#39;);
    expect(other).to.be(&#39;Other&#39;);
});
doSomething("Other");
Nach dem Login kopieren

Bevor wir fortfahren, muss noch erklärt werden, dass wir im Funktionskörper von doSomething die Assertionsbibliothek „expect.js“ verwenden, um die Richtigkeit des Codes sicherzustellen. Hier gibt es etwas Ähnliches wie die Idee von TDD (testdriven development).

Jetzt beginnen wir offiziell mit dem Schreiben unseres injectorModuls. Erstens sollte es ein Monolith sein, damit es in jedem Teil unserer Anwendung die gleiche Funktionalität hat.

var injector = {
    dependencies: {},
    register: function(key, value) {
        this.dependencies[key] = value;
    },
    resolve: function(deps, func, scope) {

    }
}
Nach dem Login kopieren

这个对象非常的简单,其中只包含两个函数以及一个用于存储目的的变量。我们需要做的事情是检查deps数组,然后在dependencies变量种寻找答案。剩余的部分,则是使用.apply方法去调用我们传递的func变量:

resolve: function(deps, func, scope) {
    var args = [];
    for(var i=0; i<deps.length, d=deps[i]; i++) {
        if(this.dependencies[d]) {
            args.push(this.dependencies[d]);
        } else {
            throw new Error(&#39;Can\&#39;t resolve &#39; + d);
        }
    }
    return function() {
        func.apply(scope || {}, args.concat(Array.prototype.slice.call(arguments, 0)));
    }        
}
Nach dem Login kopieren

如果你需要指定一个作用域,上面的代码也能够正常的运行。

在上面的代码中,Array.prototype.slice.call(arguments, 0)的作用是将arguments变量转换为一个真正的数组。到目前为止,我们的代码可以完美的通过测试。但是这里的问题是我们必须要将需要的模块写两次,而且不能够随意排列顺序。额外的参数总是排在所有的依赖项之后。

反射(reflection)方法

根据维基百科中的解释,反射(reflection)指的是程序可以在运行过程中,一个对象可以修改自己的结构和行为。在JavaScript中,简单来说就是阅读一个对象的源码并且分析源码的能力。还是回到我们的doSomething方法,如果你调用doSomething.to<a href="http://www.php.cn/wiki/57.html" target="_blank">String</a>()方法,你可以获得下面的字符串:

"function (service, router, other) {
    var s = service();
    var r = router();
}"
Nach dem Login kopieren

这样一来,只要使用这个方法,我们就可以轻松的获取到我们想要的参数,以及更重要的一点就是他们的名字。这也是AngularJS实现依赖注入所使用的方法。在AngularJS的代码中,我们可以看到下面的正则表达式

/^function\s*[^\(]*\(\s*([^\)]*)\)/m
Nach dem Login kopieren

我们可以将resolve方法修改成如下所示的代码:

resolve: function() {
    var func, deps, scope, args = [], self = this;
    func = arguments[0];
    deps = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1].replace(/ /g, &#39;&#39;).split(&#39;,&#39;);
    scope = arguments[1] || {};
    return function() {
        var a = Array.prototype.slice.call(arguments, 0);
        for(var i=0; i<deps.length; i++) {
            var d = deps[i];
            args.push(self.dependencies[d] && d != &#39;&#39; ? self.dependencies[d] : a.shift());
        }
        func.apply(scope || {}, args);
    }        
}
Nach dem Login kopieren

我们使用上面的正则表达式去匹配我们定义的函数,我们可以获取到下面的结果:

["function (service, router, other)", "service, router, other"]
Nach dem Login kopieren

此时,我们只需要第二项。但是一旦我们去除了多余的空格并以,来切分字符串以后,我们就得到了deps数组。下面的代码就是我们进行修改的部分:

var a = Array.prototype.slice.call(arguments, 0);
...
args.push(self.dependencies[d] && d != &#39;&#39; ? self.dependencies[d] : a.shift());
Nach dem Login kopieren

在上面的代码中,我们遍历了依赖项目,如果其中有缺失的项目,如果依赖项目中有缺失的部分,我们就从arguments对象中获取。如果一个数组是空数组,那么使用shift方法将只会返回undefined,而不会抛出一个错误。到目前为止,新版本的injector看起来如下所示:

var doSomething = injector.resolve(function(service, other, router) {
    expect(service().name).to.be(&#39;Service&#39;);
    expect(router().name).to.be(&#39;Router&#39;);
    expect(other).to.be(&#39;Other&#39;);
});
doSomething("Other");
Nach dem Login kopieren

在上面的代码中,我们可以随意混淆依赖项的顺序。

但是,没有什么是完美的。反射方法的依赖注入存在一个非常严重的问题。当代码简化时,会发生错误。这是因为在代码简化的过程中,参数的名称发生了变化,这将导致依赖项无法解析。例如:

var doSomething=function(e,t,n){var r=e();var i=t()}
Nach dem Login kopieren

因此我们需要下面的解决方案,就像AngularJS中那样:

var doSomething = injector.resolve([&#39;service&#39;, &#39;router&#39;, function(service, router) {

}]);
Nach dem Login kopieren

这和最一开始看到的AMD的解决方案很类似,于是我们可以将上面两种方法整合起来,最终代码如下所示:

var injector = {
    dependencies: {},
    register: function(key, value) {
        this.dependencies[key] = value;
    },
    resolve: function() {
        var func, deps, scope, args = [], self = this;
        if(typeof arguments[0] === &#39;string&#39;) {
            func = arguments[1];
            deps = arguments[0].replace(/ /g, &#39;&#39;).split(&#39;,&#39;);
            scope = arguments[2] || {};
        } else {
            func = arguments[0];
            deps = func.toString().match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1].replace(/ /g, &#39;&#39;).split(&#39;,&#39;);
            scope = arguments[1] || {};
        }
        return function() {
            var a = Array.prototype.slice.call(arguments, 0);
            for(var i=0; i<deps.length; i++) {
                var d = deps[i];
                args.push(self.dependencies[d] && d != &#39;&#39; ? self.dependencies[d] : a.shift());
            }
            func.apply(scope || {}, args);
        }        
    }
}
Nach dem Login kopieren

这一个版本的resolve方法可以接受两个或者三个参数。下面是一段测试代码:

var doSomething = injector.resolve(&#39;router,,service&#39;, function(a, b, c) {
    expect(a().name).to.be(&#39;Router&#39;);
    expect(b).to.be(&#39;Other&#39;);
    expect(c().name).to.be(&#39;Service&#39;);
});
doSomething("Other");
Nach dem Login kopieren

你可能注意到了两个逗号之间什么都没有,这并不是错误。这个空缺是留给Other这个参数的。这就是我们控制参数顺序的方法。

结语

在上面的内容中,我们介绍了几种JavaScript中依赖注入的方法,希望本文能够帮助你开始使用依赖注入这个技巧,并且写出依赖注入风格的代码。

Das obige ist der detaillierte Inhalt vonDetaillierte Analyse des Beispielcodes für die Abhängigkeitsinjektion in JavaScript. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Spracherkennungssystem mit WebSocket und JavaScript Dec 17, 2023 pm 02:54 PM

So implementieren Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem. Einführung: Mit der kontinuierlichen Weiterentwicklung der Technologie ist die Spracherkennungstechnologie zu einem wichtigen Bestandteil des Bereichs der künstlichen Intelligenz geworden. Das auf WebSocket und JavaScript basierende Online-Spracherkennungssystem zeichnet sich durch geringe Latenz, Echtzeit und plattformübergreifende Eigenschaften aus und hat sich zu einer weit verbreiteten Lösung entwickelt. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Spracherkennungssystem implementieren.

WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen WebSocket und JavaScript: Schlüsseltechnologien zur Implementierung von Echtzeitüberwachungssystemen Dec 17, 2023 pm 05:30 PM

WebSocket und JavaScript: Schlüsseltechnologien zur Realisierung von Echtzeit-Überwachungssystemen Einführung: Mit der rasanten Entwicklung der Internet-Technologie wurden Echtzeit-Überwachungssysteme in verschiedenen Bereichen weit verbreitet eingesetzt. Eine der Schlüsseltechnologien zur Erzielung einer Echtzeitüberwachung ist die Kombination von WebSocket und JavaScript. In diesem Artikel wird die Anwendung von WebSocket und JavaScript in Echtzeitüberwachungssystemen vorgestellt, Codebeispiele gegeben und deren Implementierungsprinzipien ausführlich erläutert. 1. WebSocket-Technologie

Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Verwendung von JavaScript und WebSocket zur Implementierung eines Echtzeit-Online-Bestellsystems Dec 17, 2023 pm 12:09 PM

Einführung in die Verwendung von JavaScript und WebSocket zur Implementierung eines Online-Bestellsystems in Echtzeit: Mit der Popularität des Internets und dem Fortschritt der Technologie haben immer mehr Restaurants damit begonnen, Online-Bestelldienste anzubieten. Um ein Echtzeit-Online-Bestellsystem zu implementieren, können wir JavaScript und WebSocket-Technologie verwenden. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das auf dem TCP-Protokoll basiert und eine bidirektionale Kommunikation zwischen Client und Server in Echtzeit realisieren kann. Im Echtzeit-Online-Bestellsystem, wenn der Benutzer Gerichte auswählt und eine Bestellung aufgibt

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript Dec 17, 2023 am 09:39 AM

So implementieren Sie ein Online-Reservierungssystem mit WebSocket und JavaScript. Im heutigen digitalen Zeitalter müssen immer mehr Unternehmen und Dienste Online-Reservierungsfunktionen bereitstellen. Es ist von entscheidender Bedeutung, ein effizientes Online-Reservierungssystem in Echtzeit zu implementieren. In diesem Artikel wird erläutert, wie Sie mit WebSocket und JavaScript ein Online-Reservierungssystem implementieren, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist WebSocket? WebSocket ist eine Vollduplex-Methode für eine einzelne TCP-Verbindung.

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Dec 17, 2023 pm 05:13 PM

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Wettervorhersagesystems Einführung: Heutzutage ist die Genauigkeit von Wettervorhersagen für das tägliche Leben und die Entscheidungsfindung von großer Bedeutung. Mit der Weiterentwicklung der Technologie können wir genauere und zuverlässigere Wettervorhersagen liefern, indem wir Wetterdaten in Echtzeit erhalten. In diesem Artikel erfahren Sie, wie Sie mit JavaScript und WebSocket-Technologie ein effizientes Echtzeit-Wettervorhersagesystem aufbauen. In diesem Artikel wird der Implementierungsprozess anhand spezifischer Codebeispiele demonstriert. Wir

Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Einfaches JavaScript-Tutorial: So erhalten Sie den HTTP-Statuscode Jan 05, 2024 pm 06:08 PM

JavaScript-Tutorial: So erhalten Sie HTTP-Statuscode. Es sind spezifische Codebeispiele erforderlich. Vorwort: Bei der Webentwicklung ist häufig die Dateninteraktion mit dem Server erforderlich. Bei der Kommunikation mit dem Server müssen wir häufig den zurückgegebenen HTTP-Statuscode abrufen, um festzustellen, ob der Vorgang erfolgreich ist, und die entsprechende Verarbeitung basierend auf verschiedenen Statuscodes durchführen. In diesem Artikel erfahren Sie, wie Sie mit JavaScript HTTP-Statuscodes abrufen und einige praktische Codebeispiele bereitstellen. Verwenden von XMLHttpRequest

JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Bildverarbeitungssystems JavaScript und WebSocket: Aufbau eines effizienten Echtzeit-Bildverarbeitungssystems Dec 17, 2023 am 08:41 AM

JavaScript ist eine in der Webentwicklung weit verbreitete Programmiersprache, während WebSocket ein Netzwerkprotokoll für die Echtzeitkommunikation ist. Durch die Kombination der leistungsstarken Funktionen beider können wir ein effizientes Echtzeit-Bildverarbeitungssystem erstellen. In diesem Artikel wird erläutert, wie dieses System mithilfe von JavaScript und WebSocket implementiert wird, und es werden spezifische Codebeispiele bereitgestellt. Zunächst müssen wir die Anforderungen und Ziele des Echtzeit-Bildverarbeitungssystems klären. Angenommen, wir haben ein Kameragerät, das Bilddaten in Echtzeit sammeln kann

So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript So erhalten Sie auf einfache Weise HTTP-Statuscode in JavaScript Jan 05, 2024 pm 01:37 PM

Einführung in die Methode zum Abrufen des HTTP-Statuscodes in JavaScript: Bei der Front-End-Entwicklung müssen wir uns häufig mit der Interaktion mit der Back-End-Schnittstelle befassen, und der HTTP-Statuscode ist ein sehr wichtiger Teil davon. Das Verstehen und Abrufen von HTTP-Statuscodes hilft uns, die von der Schnittstelle zurückgegebenen Daten besser zu verarbeiten. In diesem Artikel wird erläutert, wie Sie mithilfe von JavaScript HTTP-Statuscodes erhalten, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist ein HTTP-Statuscode? HTTP-Statuscode bedeutet, dass der Dienst den Dienst anfordert, wenn er eine Anfrage an den Server initiiert

See all articles