Nowadays, every framework is being modularized, even front-end javascript is no exception. Each module is responsible for certain functions, and there are interdependencies between modules. So the question arises: How to implement dependency injection in JavaScript? (Dependency injection of JavaScript has corresponding implementations in all major frameworks. Here we only learn the implementation ideas)
The following requirements:
Assume that there is already a defined service module Key-Value set, func is the new service added, and the parameter list is the service dependency.
Through some mechanism (reflection?), take out the parameter list defined by the func and assign values one by one. Then instantiate the func through some mechanism (Activitor?).
Solution:
1. Get the parameter list of func:
How to get the parameter list? The first thing that comes to my mind is the reflection mechanism. So is there reflection in javascript? There should be. Currently, I only know how to use the eval(str) function, but it seems that there is no relevant implementation for obtaining the parameter list. Looking at the func.arguments definition again, this property is only valid when func is called and parameters are passed, and it cannot meet the requirements.
Can we get the parameter list by processing the string after func.toString()?
Get started and try it:
2. Find dependencies based on the parameter list:
After getting the parameter list, that is, getting the dependency list, it is very simple to pass in the dependencies as parameters.
We know that there are two functions called func.constructor in javascript: call(thisArg,[arg[,arg,[arg,[…]]]]) and apply(thisArg,args…), both of which can be instantiated. func operation. The first parameter of the call function is this pointer, and the rest is the parameter list. This is suitable for use when the func parameter list is known, but does not meet my needs. Looking at the second apply function, the first parameter is also this pointer, and the second parameter is the parameter array. When it is called, it will automatically assign values to the parameter list of func one by one, which just meets my needs.
The code is roughly as follows:
4. Print and test:
Full code:
// Get the parameter list of func (dependency list)
GetFuncParams = function (func) {
var matches = func.toString().match(/^functions*[^(]*(s*([^)]*))/m);
If (matches && matches.length > 1)
return matches[1].replace(/s /, '').split(',');
return [];
},
// Fill in parameters (dependencies) based on parameter list (dependency list)
setFuncParams = function (params) {
for (var i in params) {
params[i] = services[params[i]];
}
return params;
};
// Activator
function Activitor(func) {
var obj = {};
func.apply(obj, setFuncParams(getFuncParams(func)));
Return obj;
}
//Define new Service
function Service(abc, ghi) {
This.write = function () {
console.log(abc);
console.log(ghi);
}
}
// Instantiate Service and call method
var service = Activitor(Service);
service.write();