ホームページ ウェブフロントエンド jsチュートリアル JavaScript_javascript スキルにおける依存性注入の詳細な説明

JavaScript_javascript スキルにおける依存性注入の詳細な説明

May 16, 2016 pm 04:08 PM
javascript 依存性注入

コンピューター プログラミングの世界は、実際には、単純な部分を常に抽象化し、これらの抽象概念を整理するプロセスです。 JavaScript も例外ではありません。私たちが JavaScript を使用してアプリケーションを作成するとき、有名なオープン ソース ライブラリやフレームワークなど、他の人が作成したコードを使用するのでしょうか。プロジェクトが成長するにつれて、依存する必要のあるモジュールがますます増えており、現時点では、これらのモジュールを効果的に編成する方法が非常に重要な問題となっています。依存関係の注入は、コードに依存するモジュールを効果的に編成する方法の問題を解決します。有名なフロントエンド フレームワーク AngularJS など、一部のフレームワークやライブラリで「依存性注入」という用語を聞いたことがあるかもしれません。依存性注入は非常に重要な機能の 1 つです。ただし、依存性注入はまったく新しいものではありません。PHP などの他のプログラミング言語には以前から存在していました。同時に、依存関係の注入は想像されているほど複雑ではありません。この記事では、JavaScript における依存性注入の概念を学び、「依存性注入スタイル」のコードの書き方をわかりやすく説明します。

目標設定

今、2 つのモジュールがあると仮定します。最初のモジュールは Ajax リクエストの送信に使用され、2 番目のモジュールはルーターとして使用されます。

コードをコピー コードは次のとおりです:

var service = function() {
Return { name: 'サービス' };
}
var router = function() {
Return { 名前: 'ルーター' };
}

現時点では、上記の 2 つのモジュールの使用を必要とする関数を作成しました:
コードをコピー コードは次のとおりです:

var doSomething = function(other) {
var s = サービス();
var r = router();
};

ここで、コードをより興味深いものにするために、このパラメータはさらにいくつかのパラメータを受け取る必要があります。もちろん、上記のコードを完全に使用することはできますが、上記のコードはどの面から見ても柔軟性が若干劣ります。使用する必要があるモジュールの名前が ServiceXML または ServiceJSON に変更された場合はどうなりますか?あるいは、テスト目的で偽のモジュールを使用したい場合はどうなるでしょうか。この時点では、関数自体を編集するだけでは済みません。したがって、最初に行う必要があるのは、依存モジュールをパラメーターとして関数に渡すことです。コードは次のとおりです:
コードをコピー コードは次のとおりです:

var doSomething = function(サービス、ルーター、その他) {
var s = サービス();
var r = router();
};

上記のコードでは、必要なモジュールを正確に渡します。しかし、これは新たな問題を引き起こします。コードの両方の部分で doSomething メソッドを呼び出すとします。この時点で、3 番目の依存関係が必要な場合はどうなるでしょうか。現時点では、すべての関数呼び出しコードを編集するのは賢明な考えではありません。したがって、これを行うにはコードが必要です。これは、依存性インジェクターが解決しようとしている問題です。これで目標を設定できます:

1. 依存関係を登録できるはずです
2. 依存関係インジェクターは関数を受け取り、必要なリソースを取得できる関数を返す必要があります
3. コードは複雑であってはなりませんが、シンプルで親しみやすいものである必要があります
4. 依存関係インジェクターは、渡された関数スコープを維持する必要があります
5. 渡された関数は、記述された依存関係だけでなく、カスタム パラメーターを受け取ることができる必要があります

JS/AMD メソッドが必要

おそらく、有名な requirejs について聞いたことがあるでしょう。これは、依存関係注入の問題を非常にうまく解決できるライブラリです。

コードをコピー コードは次のとおりです:

define(['サービス', 'ルータ'], function(サービス, ルータ) {
// ...
});

requirejs の考え方は、最初に必要なモジュールを記述してから、独自の関数を記述する必要があるということです。中でもパラメータの順序は重要です。同様の構文を実装できる injector というモジュールを作成する必要があるとします。
コードをコピー コードは次のとおりです:

var doSomething = injector.resolve(['service', 'router'], function(service, router, other) {
Expect(service().name).to.be('Service');
Expect(router().name).to.be('ルーター');
Expect(other).to.be('Other');
});
doSomething("その他");

先に進む前に、doSomething の関数本体で、expect.js アサーション ライブラリを使用してコードの正確さを確認する必要があることを 1 つ説明する必要があります。ここにはTDD(テスト駆動開発)の考え方に似たものがあります。

ここで、インジェクター モジュールの作成を正式に開始します。まず、アプリケーションのすべての部分で同じ機能を持たせるために、モノリスである必要があります。

コードをコピー コードは次のとおりです:

var インジェクター = {
依存関係: {}、
レジスタ: function(key, value) {
This.dependency[key] = 値;
}、
解決: function(deps, func,scope) {

}
}


このオブジェクトは非常に単純で、2 つの関数と保存用の変数のみが含まれています。私たちがしなければならないことは、deps 配列をチェックし、依存関係変数で答えを探すことです。残りの部分は、.apply メソッドを使用して、渡した func 変数を呼び出すことです:
コードをコピー コードは次のとおりです:

解決: function(deps, func,scope) {
var args = [];
for(var i=0; i if(this.dependency[d]) {
args.push(this.dependency[d]);
} else {
throw new Error('Can'tsolve ' d);
}
}
戻り関数() {
func.apply(scope || {}, args.concat(Array.prototype.slice.call(arguments, 0)));
                                             }

スコープを指定する必要がある場合は、上記のコードも通常どおり実行できます。

上記のコードでは、Array.prototype.slice.call(arguments, 0) の機能は、引数変数を実数の配列に変換することです。これまでのところ、私たちのコードはテストに完全に合格しています。しかし、ここでの問題は、必要なモジュールを 2 回書かなければならず、それらを任意の順序で配置できないことです。追加のパラメーターは常にすべての依存関係の後に来ます。

反映方法

Wikipedia の説明によると、リフレクションとは、プログラムの実行中にオブジェクトが自身の構造や動作を変更できることを意味します。 JavaScriptでは、簡単に言えば、オブジェクトのソースコードを読み取って、ソースコードを解析する機能です。 doSomething メソッドに戻りますが、doSomething.toString() メソッドを呼び出すと、次の文字列を取得できます:


コードをコピー コードは次のとおりです:
"関数 (サービス、ルーター、その他) {
var s = サービス();
var r = router();
}"

このように、このメソッドを使用する限り、必要なパラメータ、そしてさらに重要なことに、その名前を簡単に取得できます。これは、AngularJS が依存関係の注入を実装するために使用するメソッドでもあります。 AngularJS コードでは、次の正規表現が確認できます:

コードをコピー コードは次のとおりです:
/^関数*[^(]*(s*([^)]*))/m


解決メソッドを以下に示すコードに変更できます:

コードをコピーします コードは次のとおりです:

解決: function() {
var func、deps、scope、args = []、self = this;
func = 引数[0];
deps = func.toString().match(/^functions*[^(]*(s*([^)]*))/m)[1].replace(/ /g, '').split(' 、');
スコープ = 引数[1] {};
戻り関数() {
var a = Array.prototype.slice.call(arguments, 0);
for(var i=0; i var d = deps[i];
args.push(self.dependency[d] && d != '' ? self.dependency[d] : a.shift());
}
func.apply(scope || {}, args);
                                             }

上記の正規表現を使用して定義した関数と一致させると、次の結果が得られます:


コードをコピー コードは次のとおりです:
["機能(サービス、ルーター、その他)"、"サービス、ルーター、その他"]

この時点で必要なのは 2 番目の項目だけです。ただし、余分なスペースを削除し、文字列を で分割すると、deps 配列が得られます。次のコードは、変更した部分です:

コードをコピー コードは次のとおりです:
var a = Array.prototype.slice.call(arguments, 0);
...
args.push(self.dependency[d] && d != '' ? self.dependency[d] : a.shift());

上記のコードでは、依存プロジェクトを走査し、依存プロジェクトに欠落している部分がある場合は、それらを引数オブジェクトから取得します。配列が空の場合、shift メソッドを使用すると、エラーはスローされずに単純に unknown が返されます。これまでのところ、インジェクターの新しいバージョンは次のようになります:


コードをコピー コードは次のとおりです:
var doSomething = injector.resolve(function(service, other, router) {
Expect(service().name).to.be('Service');
Expect(router().name).to.be('ルーター');
Expect(other).to.be('Other');
});
doSomething("その他");

上記のコードでは、依存関係の順序を自由に混ぜることができます。

しかし、完璧なものはありません。リフレクティブ メソッドの依存性注入には非常に深刻な問題があります。コードを単純化するとエラーが発生します。これは、コードの簡略化プロセス中にパラメーターの名前が変更され、依存関係の解決に失敗する可能性があるためです。例:


コードをコピー コードは次のとおりです:
var doSomething=function(e,t,n){var r=e();var i=t()}

したがって、AngularJS と同様に、次の解決策が必要です:

コードをコピー コードは次のとおりです:
var doSomething = injector.resolve(['service', 'router', function(service, router) {
}]);


これは最初に見た AMD ソリューションに非常に似ているため、上記の 2 つの方法を統合できます。最終的なコードは次のとおりです。

コードをコピー コードは次のとおりです:

var インジェクター = {
    依存関係: {}、
    register: function(key, value) {
        this.dependency[key] = 値;
    }、
    解決: function() {
        var func、deps、scope、args = []、self = this;
        if(引数の種類[0] === '文字列') {
            func = 引数[1];
            deps = argument[0].replace(/ /g, '').split(',');
            スコープ = 引数[2] || {};
        } else {
            func = 引数[0];
            deps = func.toString().match(/^functions*[^(]*(s*([^)]*))/m)[1].replace(/ /g, '').split(' 、');
            スコープ = 引数[1] || {};
        }
        return function() {
            var a = Array.prototype.slice.call(arguments, 0);
            for(var i=0; i                 var d = deps[i];
                args.push(self.dependency[d] && d != '' ? self.dependency[d] : a.shift());
            }
            func.apply(scope || {}, args);
        }
    }
}

このバージョンの解決メソッドは 2 つまたは 3 つのパラメータを受け取ることができます。

复制代码代码如下:
var doSomething = injector.resolve('router,,service', function(a, b, c) {
    Expect(a().name).to.be('ルーター');
    Expect(b).to.be('その他');
    Expect(c().name).to.be('サービス');
});
doSomething("その他");

2 つの番号の間に何も存在しないことに注意してください。これは危険な話ではありません。このスペースは他のパラメータに保持されています。これがパラメータの順序を制御する方法です。

结语

上の内容では、JavaScript での依存注入の方法を紹介しており、この技術の使用を開始し、依存注入のコードを書き出すのに役立つことを期待しています。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

Golang 関数パラメータ渡しにおける依存性注入パターン Golang 関数パラメータ渡しにおける依存性注入パターン Apr 14, 2024 am 10:15 AM

Go では、依存関係注入 (DI) モードは、値の受け渡しやポインターの受け渡しなど、関数パラメーターの受け渡しを通じて実装されます。 DI パターンでは、依存関係は通常、分離を改善し、ロック競合を軽減し、テスト容易性をサポートするためにポインターとして渡されます。ポインターを使用すると、関数はインターフェイスの種類にのみ依存するため、具体的な実装から切り離されます。また、ポインターの受け渡しにより、大きなオブジェクトを渡す際のオーバーヘッドが削減されるため、ロックの競合が軽減されます。さらに、DI パターンでは依存関係を簡単にモックできるため、DI パターンを使用した関数の単体テストを簡単に作成できます。

JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 JavaScript と WebSocket: 効率的なリアルタイム画像処理システムの構築 Dec 17, 2023 am 08:41 AM

JavaScript は Web 開発で広く使用されているプログラミング言語であり、WebSocket はリアルタイム通信に使用されるネットワーク プロトコルです。 2 つの強力な機能を組み合わせることで、効率的なリアルタイム画像処理システムを構築できます。この記事では、JavaScript と WebSocket を使用してこのシステムを実装する方法と、具体的なコード例を紹介します。まず、リアルタイム画像処理システムの要件と目標を明確にする必要があります。リアルタイムの画像データを収集できるカメラ デバイスがあるとします。

See all articles