Heim  >  Artikel  >  Web-Frontend  >  Mechanismus und private Variablen der JavaScript-Simulationsklasse

Mechanismus und private Variablen der JavaScript-Simulationsklasse

高洛峰
高洛峰Original
2016-11-25 14:31:431072Durchsuche

Bei der Verwendung einiger Javascript-Frameworks sehen Sie möglicherweise ähnlichen Code


 var MyClass = new Class({
  initialize: function(param, ...) {
this.param = param;
  ...
  },
 func1: function(...) {
   ...
  }
 });

var myObj = new MyClass(param);
myObj.func1(...);


Dies ist eine typische objektorientierte Klassenmechanismusanwendung, die sich vom nativen Javascript-Klassenmechanismus In unterscheidet Im Vergleich wirkt es klarer und natürlicher. Darüber hinaus ist es auf dieser Basis auch bequemer, die Klassenvererbung zu implementieren. Wie wird das erreicht?
Wie wir alle wissen, kann die Verwendung einer Funktion als Konstruktor ein Objekt erstellen. Der obige Code kann einfach wie folgt geschrieben werden:


function MyClass(param) {
this . param = param;
This.func1 = function(..) {
myObj.func1();

Es ist eigentlich ganz einfach und nicht schwer zu verstehen. Wenn Sie jedoch eine große Javascript-Klassenbibliothek erstellen möchten, kann es schwierig sein, aus einer Reihe von Codes herauszufinden, welche Klassen, welche Funktionen, welche Klassenmethoden und welche Klassenattribute sind.

Natürlich geht es hier nicht darum, ihre Vor- und Nachteile zu vergleichen, sondern ich bin nur neugierig, wie die neue Klasse implementiert wird.
Im obigen Code bedeutet die Verwendung einer Anweisung wie new MyClass(), dass MyClass eine Funktion sein muss, und es bedeutet auch, dass new Class ein Funktionsobjekt zurückgeben muss. Aus der wörtlichen Bedeutung ist ersichtlich, dass die Funktion initialize Es wird als Konstruktor verwendet, daher muss in der von der neuen Klasse zurückgegebenen Funktion initialize verwendet werden, um das Objekt zu initialisieren. Basierend auf dieser Analyse kann der folgende Code abgeleitet werden:


Function Class(argu) {
return function() {
var init = argu['initialize'] || ( ) {}; //Wenn kein Konstruktor initialisiert ist, verwenden Sie eine leere Funktion als Standardkonstruktor

  for(var p in argu) {

  this[p] = argu[p];
  }
   init.apply(this, arguments); //Verwenden Sie this der aktuellen Funktion, um das Original zu ersetzen
  }
 }


 Es reicht aus, um das Problem zu veranschaulichen. Sie müssen auf den Satz init.apply(this, arguments) achten. Einer davon ist this, der ursprünglich der Standardwert this in initialize war Funktion und diese anonyme Funktion ist der Konstruktor einer benutzerdefinierten Klasse, die durch eine neue Klasse erstellt wurde. Das andere sind Argumente, die sich auf die Parameter der anonymen Funktion beziehen, die der Parameter in new MyClass(param) oben ist.
Die Konvertierung ist etwas schwindelerregend. Gibt es einen einfacheren Weg? Bitte schauen Sie sich den folgenden Code an:

function Class(argu) {
var obj = argu['initialize'] || argu ) {
  obj.prototype[p] = argu[p]; //Beachten Sie, dass prototyp

hier verwendet wird   }

  return obj; // Es gibt immer noch eine Funktion zurück?br /> 🎜>

Haha, es fühlt sich viel unkomplizierter an.
Damit ist die Konstruktion eines einfachen Klassenmechanismus abgeschlossen. Mit diesem Mechanismus können Sie Klassenkonstruktoren, Methoden und Eigenschaften erstellen, diese sind jedoch offensichtlich öffentlich. Wie implementiert man also private Variablen und Methoden?
Wir wissen, dass private Variablen von Javascript-Klassen über den Schließungsmechanismus implementiert werden können. Nach der Konvertierung mit new Class({...}) ist es jedoch offensichtlich schwierig, einen effektiven Abschluss zu bilden. Wie kann man dieses Problem umgehen?
Javascript bietet zwei Methoden: eval() und die toString()-Methode des Funktionsobjekts. Ersteres ist häufiger und letzteres kann verwendet werden, um den spezifischen Code der Funktion abzurufen. Mit diesen beiden Methoden können Sie einfach die privaten Variablen der Klasse simulieren:

Function Class(argu) {
 var _ = argu['private'] || {};
eval('var obj = ' + (argu['initialize'] || function() {}).toString());
for(var p in argu) {
if(p == ' initialize ' ||. p == 'private')

continue;

if(typeof argu[p] == 'function')
eval('obj.prototype[p] = ' + argu[p ] .toString());
  else
  obj.prototype[p] = argu[p];
  }
  return obj;
 }


Durch Die Funktion Die toString()-Methode des Objekts extrahiert den Code der Funktion und führt den Code mit der Eval-Methode aus, sodass ein gültiger Abschlussbereich zur Implementierung des privaten Mechanismus erstellt werden kann. Wir können es wie folgt anwenden:


var Person = new Class({
private: {
height: 160,
Weight: 50
},
initialize: function(name, height, Weight) {
 this.name = name;
 _.height = height ||. _.height;
 _.weight = Weight ||. _.weight;
show: function( ) {
    alert('Name:' + this.name + '/nheight:' + _.height + '/nweight:' + _.weight);
  }
 });

 var my = new Person("Zh");

 my.show();

Es sieht nicht gut aus, ist aber in der tatsächlichen Anwendung nicht sehr nützlich. . Vor allem im Hinblick auf die Effizienz nimmt es etwa viermal mehr Zeit in Anspruch als die übliche Implementierung. Beim Aufbau großer Klassenbibliotheken ist dies nicht tolerierbar, aber in kleinen Anwendungen ist es einfacher und unkomplizierter, den folgenden Code zu implementieren:

Function MyClass(param) {
var privateVar = ...;
 this.param = param;

 this.func = function() {

  alert(privateVar);
  };
 }


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