Cette fois, je vous présente la réflexion JS et l'injection de dépendances analyse de cas d'utilisation, quelles sont les notes lors de l'utilisation de la réflexion JS et de l'injection de dépendances, voici des cas pratiques, prenons un regarde une fois.
La compréhension de la réflexion en javascript a toujours été que la fonction de rappel est enregistrée à l'aide d'un tableau, puis la méthode d'appel ou d'application est utilisée au moment approprié . , appelez simplement le rappel, généralement comme suit :
Définissez d'abord deux méthodes :
var service = function() { return { name: 'Service' }; } var router = function() { return { name: 'Router' }; }
Nous avons une autre fonction qui doit utiliser ces deux modules.
var doSomething = function(other) { var s = service(); var r = router(); };
Bien sûr, nous espérons pouvoir utiliser l'injection de dépendances pour le faire et confier le contrôle à l'ordinateur au lieu d'appeler manuellement ce qui suit :
var doSomething = injector.resolve('router,,service', function(a, b, c) { expect(a().name).to.be('Router'); expect(b).to.be('Other'); expect(c().name).to.be('Service'); }); doSomething("Other");
Ensuite, nous peut créer une méthode de réflexion comme suit :
var injector ={ dependencies: {}, register: function(key, value) { this.dependencies[key] = value; }, 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('Can\'t resolve ' + d); } } return function() { func.apply(scope || {}, args.concat(Array.prototype.slice.call(arguments, 0))); } } };
Comme indiqué dans le code ci-dessus, les dépendances sont utilisées pour enregistrer la collection de fonctions de rappel et la résolution est utilisée pour l'appeler.
C'est aussi une idée relativement mature et correcte.
Mais il reste encore plusieurs problèmes :
1 résolution Lors d'un appel, l'ordre de la liste des paramètres deps doit être cohérent.
2 C'est un peu tiré par les cheveux, mais ça compte. Lors de l'appel, vous devez saisir à nouveau les paramètres formels et ne pouvez pas l'appeler directement.
Afin de résoudre le problème ci-dessus, la solution suivante est donnée :
var injector ={ dependencies: {}, register: function(key, value) { this.dependencies[key] = value; }, resolve: function() { var func, deps, scope, args = [], self = this; if(typeof arguments[0] === 'string') { func = arguments[1]; deps = arguments[0].replace(/ /g, '').split(','); scope = arguments[2] || {}; } else { func = arguments[0]; deps = func.toString().match(/^function\s*[^]*\(\s*([^]*\(\s*([^]*)\)/m)[1].replace(/ /g, '').split(','); 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 != '' ? self.dependencies[d] : a.shift()); } func.apply(scope || {}, args); } } };
Utilisez des expressions régulières pour analyser le code, analysez les paramètres de la liste de fonctions, puis faites correspondre et transmettez automatiquement valeurs une par une, alors Cela peut être résolu, l'ordre doit toujours être le problème, bien sûr, c'est aussi l'approche adoptée par le framework mvvm le plus populaire AngularJs.
L'appel peut être le suivant :
injector.resolve(['service,,router', function(service, router) { }]);
Vous remarquerez peut-être qu'il y a deux virgules après le premier paramètre - note
Ce n'est pas une faute de frappe. La valeur nulle représente en fait le paramètre « Autre » (espace réservé). Cela montre comment nous contrôlons l’ordre des paramètres.
Enfin, il existe une autre façon d'injecter directement dans le scope, c'est-à-dire directement dans le scope. Ensuite, le scope est injecté, et il n'y aura aucun problème de l'ordre de passage des paramètres mentionné ci-dessus
.Car il n'y a pas besoin de passer des paramètres, directement accessibles depuis le scope.
var injector = { dependencies: {}, register: function(key, value) { this.dependencies[key] = value; }, resolve: function(deps, func, scope) { var args = []; scope = scope || {}; for(var i=0; i<deps.length, d=deps[i]; i++) { if(this.dependencies[d]) { scope[d] = this.dependencies[d]; } else { throw new Error('Can\'t resolve ' + d); } } return function() { func.apply(scope || {}, Array.prototype.slice.call(arguments, 0)); } } } var doSomething = injector.resolve(['service', 'router'], function(other) { expect(this.service().name).to.be('Service'); expect(this.router().name).to.be('Router'); expect(other).to.be('Other'); }); doSomething("Other");
Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !
Lecture recommandée :
Comment utiliser js statistiques Nombre de balises de page
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!