You must have heard of the Dependency Injection (DI) pattern, right?
Whether it is the messy Spring framework on the back end, or the front-end trend angular.js, dependency injection can be seen everywhere.
The term is a bit obscure, but the core idea is very simple.
Using a common saying, "If you want wind, you will get wind, if you want rain, you will get rain" , or "When you have food, you can open your mouth, and if you have clothes, you can reach out" .
You may still be a little confused after listening to my explanation. Let me give you an example first.
The following are some modules, they are also called "dependencies", which are stored in a hash object:
var deps = { 'firstDependency': function () {return 'this is firstDependency';}, 'secondDepency': function () {return 'this is secondDepency';}, };
The following is a dependency injection manager, which will be new when the time comes:
var DI = function (dependency) { this.dependency = dependency; };
At the time of new , just pass deps as a parameter.
Okay, now comes the crux of the problem. What we need to write:
DI.prototype.inject = function (func) {......};
This inject injection method is bound to the prototype of DI and receives A function as a parameter.
So how to use it?
var di = new DI(deps); var myDependentFunc = di.inject(function (secondDepency, firstDependency) { firstDependency(); secondDepency(); }); myDependentFunc();
Let’s first observe the anonymous function passed in inject. It represents the demand and is where we need to inject.
Let’s take a look at its formal parameters first.
secondDepency, firstDependency
There are two parameters here, which represent two requirements. When the time comes, we will analyze these two parameters and find related modules.
Okay, back to the issue of writing the inject function, what should we do in the first step?
First get the toString() form of the function passed in by inject:
//第一步 DI.prototype.inject = function (func) { func.toString(); };
Then, analyze the string, Find all formal parameters:
//第二步 DI.prototype.inject = function (func) { var args = findArgs(func.toString()); };
How to write the findArgs method? You can use regular expressions or string segmentation and interception. I use the latter here.
String.prototype.trim=function(){ return this.replace(/(^\s*)|(\s*$)/g, ""); }; var findArgs = function(funcStr){ var bracket1 = funcStr.indexOf("("); var bracket2 = funcStr.indexOf(")"); var argsStr = funcStr.slice(bracket1+1,bracket2); var args = argsStr.split(","); return args.map(function(e){ return e.trim(); }); };
After finding all the formal parameters, the third step is to find the corresponding module function from the module hash table and store it in the actual parameter list.
realArgs refers to actual parameter list:
//第三步 DI.prototype.inject = function (func) { var args = findArgs(func.toString()); var realArgs = []; for(var i=0;i<args.length;i++){ var dep = this.dependency[args[i]]; if(dep){ realArgs.push(dep); } } //...... };
The last step isInjection, inject returns an anonymous function. When the anonymous function is executed, the actual parameter list is obtained through the closure and injected into func.
DI.prototype.inject = function (func) { var args = findArgs(func.toString()); var realArgs = []; for(var i=0;i<args.length;i++){ var dep = this.dependency[args[i]]; if(dep){ realArgs.push(dep); } } return function(){ return func.apply(null,realArgs); }; }
In this way, a simple version of the injection function is completed.
The above is an interesting question about JavaScript: dependency injection. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!