JavaScript So binden Sie private Mitglieder in ein Objekt ein

Ich habe vor kurzem den Angular Cloud Data Connector entwickelt, der es Angular-Entwicklern ermöglicht, Cloud-Daten, insbesondere Azure Mobile Services, unter Verwendung von Webstandards wie indexierter DB zu verwenden. Ich habe versucht, eine Möglichkeit für JavaScript-Entwickler zu schaffen, private Mitglieder in ein Objekt einzubetten. 

Meine Technik für diesen speziellen Fall ist die Verwendung des sogenannten "Closure Space". In diesem Lernprogramm möchte ich Ihnen mitteilen, wie Sie dies für Ihre eigenen Projekte verwenden können und wie sich dies auf Leistung und Speicher für die wichtigsten Browser auswirkt.

Lassen Sie mich jedoch kurz darauf eingehen, warum Sie private Mitglieder benötigen und eine alternative Möglichkeit, private Mitglieder zu „simulieren“.

Fühlen Sie sich frei, mich auf Twitter zu kontaktieren, wenn Sie diesen Artikel besprechen möchten: @deltakosh.

1. Warum private Mitglieder verwenden?

Wenn Sie ein Objekt mit JavaScript erstellen, können Sie Wertmitglieder definieren. Wenn Sie den Lese- / Schreibzugriff darauf steuern möchten, benötigen Sie Zugriffsmethoden, die folgendermaßen definiert werden können:

var entity = ; entity._property = "Hallo Welt"; Object.defineProperty (Entität, "Eigenschaft", get: function () return this._property;, set: function (value) this._property = value;, Aufzählbar: true, konfigurierbar: true);

Auf diese Weise haben Sie die volle Kontrolle über Lese- und Schreibvorgänge. Das Problem ist, dass die _Eigentum Mitglied ist noch erreichbar und kann direkt geändert werden.

Genau aus diesem Grund benötigen Sie eine robustere Methode zum Definieren privater Member, auf die nur die Funktionen des Objekts zugreifen können.

2. Closure Space verwenden

Die Lösung ist, Schließraum zu verwenden. Dieser Speicherplatz wird vom Browser jedes Mal erstellt, wenn eine innere Funktion auf Variablen aus dem Bereich einer äußeren Funktion zugreifen kann. Dies kann manchmal schwierig sein, aber für unser Thema ist dies eine perfekte Lösung.

Ändern wir also den vorherigen Code, um diese Funktion zu verwenden:

var createProperty = function (obj, prop, currentValue) Object.defineProperty (obj, prop, get: function () return currentValue;, set: function (value) currentValue = value;, Aufzählung: true, konfigurierbar : wahr );  var entity = ; var myVar = "Hallo Welt"; createProperty (Entität, "Eigenschaft", MyVar);

In diesem Beispiel ist die createProperty Funktion hat eine aktueller Wert Variable, die get- und set-Funktionen sehen kann. Diese Variable wird im Schließraum von get- und set-Funktionen gespeichert. Nur diese beiden Funktionen können jetzt das sehen und aktualisieren aktueller Wert Variable! Mission erfüllt!

Der einzige Nachteil, den wir hier haben, ist, dass der Quellwert (myVar) ist noch erreichbar. Hier ist eine weitere Version für noch robusteren Schutz:

var createProperty = Funktion (obj, prop) var currentValue = obj [prop]; Object.defineProperty (obj, prop, get: function () return currentValue;, set: function (value) currentValue = value;, Aufzählung: true, konfigurierbar: true);  var entity = Eigenschaft: "Hallo Welt"; createProperty (Entität, "Eigenschaft");

Bei dieser Methode wird sogar der Quellwert zerstört. Mission voll erfüllt!

3. Überlegungen zur Leistung

Lassen Sie uns nun einen Blick auf die Leistung werfen.

Offensichtlich sind Schließräume oder sogar Eigenschaften langsamer und teurer als nur eine einfache Variable. Deshalb konzentriert sich dieser Artikel mehr auf den Unterschied zwischen der regulären Methode und der Schließraumtechnik.

Um zu bestätigen, dass der Closed-Space-Ansatz im Vergleich zur Standardmethode nicht zu teuer ist, schrieb ich diesen kleinen Benchmark:

       
Computing…

Ich erstelle 1 Million Objekte, alle mit einem Eigenschaftsmitglied. Dann mache ich drei Tests:

  • Machen Sie 1 Million zufällige Zugriffe auf die Immobilie.
  • Machen Sie 1 Million Direktzugriffe auf die "Closure Space" -Version.
  • Machen Sie 1 Million Direktzugriffe auf die reguläre Get / Set-Version.

Hier sind eine Tabelle und ein Diagramm der Ergebnisse:

Wir können sehen, dass die Closed-Space-Version immer schneller als die reguläre Version und je nach Browser ist, Es kann eine wirklich beeindruckende Optimierung sein.

Die Leistung von Chrome ist geringer als ich erwartet hatte. Es könnte einen Fehler geben. Um sicher zu gehen, habe ich das Google-Team kontaktiert, um herauszufinden, was hier passiert. Wenn Sie testen möchten, wie sich dies im neuen Microsoft Edge-Microsoft-Browser auswirkt, der standardmäßig mit Windows 10 ausgeliefert wird, können Sie ihn hier herunterladen.

Bei genauerer Betrachtung können wir jedoch feststellen, dass die Verwendung von Sperrräumen oder sogar einer Eigenschaft zehnmal langsamer sein kann als der direkte Zugriff auf ein Mitglied. Seien Sie also gewarnt und verwenden Sie es weise.

4. Speicherfußabdruck

Wir müssen auch sicherstellen, dass diese Technik nicht zu viel Speicher verbraucht. Um das Gedächtnis zu messen, habe ich diese drei Code-Teile geschrieben:

Referenzcode

var sampleSize = 1000000; var Entitäten = []; // Erstellen von Entitäten für (var index = 0; index) < sampleSize; index++)  entities.push( property: "hello world (" + index + ")" ); 

Normaler Weg

var sampleSize = 1000000; var Entitäten = []; // Eigenschaft hinzufügen und lokales Mitglied verwenden, um privaten Wert für (var index = 0; index) zu speichern < sampleSize; index++)  var entity = ; entity._property = "hello world (" + index + ")"; Object.defineProperty(entity, "property",  get: function ()  return this._property; , set: function (value)  this._property = value; , enumerable: true, configurable: true ); entities.push(entity); 

Closure Space-Version

var sampleSize = 1000000; var Entitäten = []; var createProperty = function (obj, prop, currentValue) Object.defineProperty (obj, prop, get: function () return currentValue;, set: function (value) currentValue = value;, Aufzählung: true, konfigurierbar : wahr );  // Hinzufügen von Eigenschaften und Verwenden eines Schließbereichs zum Speichern des privaten Werts für (var index = 0; index) < sampleSize; index++)  var entity = ; var currentValue = "hello world (" + index + ")"; createProperty(entity, "property", currentValue); entities.push(entity); 

Dann habe ich all diese drei Codes ausgeführt und den Embedded-Memory-Profiler gestartet (Beispiel hier mit F12-Tools):

Hier sind die Ergebnisse, die ich auf meinem Computer erhalten habe:

Zwischen Verschlussraum und normaler Weise hat nur Chrome etwas bessere Ergebnisse für die Verschlussraumversion. IE11 und Firefox benötigen etwas mehr Speicher, aber die Browser sind relativ vergleichbar. Benutzer werden wahrscheinlich keinen Unterschied zu den modernen Browsern feststellen.

Weitere praktische Übungen mit JavaScript

Es mag Sie ein wenig überraschen, aber Microsoft bietet eine Reihe von kostenlosen Informationen zu vielen Open-Source-JavaScript-Themen. Wir haben uns zum Ziel gesetzt, mit Microsoft Edge viel mehr zu schaffen. Schauen Sie sich meine eigenen an:

  • Einführung in WebGL 3D mit HTML5 und Babylon.JS
  • Erstellen einer Einzelseitenanwendung mit ASP.NET und AngularJS
  • Schneide Grafiken in HTML

Oder die Lernreihe unseres Teams:

  • Praktische Tipps zur Leistung, um Ihr HTML / JavaScript schneller zu machen (eine siebteilige Serie vom responsiven Design über Gelegenheitsspiele bis hin zur Leistungsoptimierung)
  • The Modern Web Platform Jump Start (Grundlagen von HTML, CSS und JS)
  • Universelle Windows-Apps mit HTML und JavaScript entwickeln Jump Start (Verwenden Sie zur Erstellung einer App das bereits erstellte JS).

Und einige kostenlose Tools: Visual Studio Community, Azure Trial und Cross-Browser-Testtools für Mac, Linux oder Windows.

Fazit

Wie Sie sehen können, können Schließraumeigenschaften a sein gute Möglichkeit, wirklich private Daten zu erstellen. Möglicherweise müssen Sie mit einem geringfügigen Anstieg des Speicherverbrauchs rechnen, aber aus meiner Sicht ist dies ziemlich vernünftig (und zu diesem Preis können Sie eine deutliche Leistungsverbesserung gegenüber dem regulären Betrieb erzielen)..

Und wenn Sie es selbst ausprobieren möchten, finden Sie hier den gesamten Code. Hier finden Sie eine gute Anleitung für Azure Mobile Services.

Dieser Artikel ist Teil der Web-Dev-Tech-Serie von Microsoft. Wir freuen uns zu teilen Microsoft Edge und das Neue EdgeHTML-Rendering-Engine mit dir. Erhalten Sie kostenlose virtuelle Maschinen oder testen Sie remote auf Ihrem Mac, iOS, Android oder Windows-Gerät. http://dev.modern.ie/.

Lernen Sie JavaScript: Das komplette Handbuch

Wir haben ein umfassendes Handbuch zusammengestellt, mit dessen Hilfe Sie JavaScript erlernen können, egal ob Sie gerade erst als Webentwickler anfangen oder sich mit fortgeschrittenen Themen befassen möchten.