Heim  >  Artikel  >  Web-Frontend  >  Anwendungsfallanalyse für JS-Reflexion und Abhängigkeitsinjektion

Anwendungsfallanalyse für JS-Reflexion und Abhängigkeitsinjektion

php中世界最好的语言
php中世界最好的语言Original
2018-05-31 14:37:521487Durchsuche

Dieses Mal bringe ich Ihnen eine Anwendungsfallanalyse für JS Reflection und Dependency Injection. Was sind die Hinweise bei der Verwendung von JS Reflection und Dependency Injection? schau mal.

Das Verständnis der Reflexion in Javascript war schon immer, dass die Rückruffunktion mithilfe eines Arrays gespeichert wird und dann zum entsprechenden Zeitpunkt die Methode call oder apply verwendet wird . Rufen Sie einfach den Rückruf auf:

Definieren Sie zunächst zwei Methoden:

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

Wir haben eine weitere Funktion, die diese beiden Module verwenden muss.

var doSomething = function(other) {
  var s = service();
  var r = router();
};

Natürlich hoffen wir, dass wir dazu die Abhängigkeitsinjektion verwenden und die Kontrolle an den Computer übergeben können, anstatt Folgendes manuell aufzurufen:

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");

Dann können wir eine Reflexion erstellen Methode wie folgt:

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)));
      }
    }
};

Wie im obigen Code gezeigt, werden Abhängigkeiten verwendet, um die Rückruffunktionssammlung zu speichern, und „resolve“ wird verwendet, um sie aufzurufen.

Dies ist auch eine relativ ausgereifte und gute Idee.

Aber es gibt immer noch mehrere Probleme:

1 Lösung Bei einem Anruf muss die Reihenfolge der Deps-Parameterliste konsistent sein.

2 Das ist etwas weit hergeholt, aber es zählt. Beim Aufruf müssen Sie die Formalparameter erneut eingeben und können nicht direkt aufrufen.

Um das obige Problem zu lösen, wird die folgende Lösung gegeben:

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);
      }
    }
};

Verwenden Sie reguläre Regeln, um den Code zu analysieren, die Funktionslistenparameter zu analysieren und dann automatisch Werte abzugleichen und zu übergeben ​​Eins nach dem anderen, dann können Sie die Reihenfolge immer beibehalten, um das Problem zu lösen. Dies ist natürlich auch der Ansatz des heißesten MVVM-Frameworks AngularJs.

Die aufrufende Methode kann wie folgt aussehen:

injector.resolve(['service,,router', function(service, router) {
}]);

Sie bemerken möglicherweise, dass nach dem ersten Parameter zwei Kommas stehen – Hinweis

Dies ist kein Tippfehler. Der Nullwert stellt tatsächlich den Parameter „Andere“ (Platzhalter) dar. Dies zeigt, wie wir die Reihenfolge der Argumente steuern.

Schließlich gibt es noch eine andere Möglichkeit, direkt in den Bereich zu injizieren. Dann wird der Bereich injiziert, und es gibt kein Problem mit der oben genannten Reihenfolge der Parameterübergabe

Da keine Parameter übergeben werden müssen, auf die direkt vom Bereich aus zugegriffen werden kann.

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");

Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!

Empfohlene Lektüre:

So entwickeln Sie die Funktion zur Eingabe eines Bestätigungscode-Passworts im WeChat-Miniprogramm

So verwenden Sie js Statistiken Anzahl der Seiten-Tags

Das obige ist der detaillierte Inhalt vonAnwendungsfallanalyse für JS-Reflexion und Abhängigkeitsinjektion. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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