Heim > Web-Frontend > js-Tutorial > Hauptteil

Beispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild)

黄舟
Freigeben: 2017-03-11 15:27:53
Original
1481 Leute haben es durchsucht

Kürzlich habe ich das Projekt „Angular Cloud Data Connector“ entwickelt, um Angular-Entwicklern dabei zu helfen, Cloud-Daten, insbesondere Azure-Mobildienste, mithilfe von WEB-Standards wie indizierter Datenbanken zu nutzen. Ich versuche, JavaScript-Entwicklern eine Möglichkeit zu bieten, private Mitglieder in ein Objekt einzubetten.

Meine Technik zur Lösung dieses Problems verwendet den von mir als Abschluss bezeichneten Raum. In diesem Einführungsartikel möchte ich erläutern, wie Sie es in Ihren Projekten verwenden und welche Auswirkungen es auf Leistung und Speicher in den wichtigsten Browsern hat.

Bevor wir uns eingehend damit befassen, sprechen wir zunächst darüber, warum Sie private Mitglieder verwenden müssen, und es gibt eine alternative Möglichkeit, private Mitglieder zu simulieren.

Wenn Sie diesen Artikel kommentieren möchten, können Sie mir gerne einen Tweet senden: @deltakosh.

1. Warum private Mitglieder verwenden

Wenn Sie ein Objekt in JavaScript erstellen, können Sie Wertmitglieder deklarieren. Wenn Sie den Lese-/Schreibzugriff darauf steuern möchten, können Sie dies wie folgt deklarieren:

var entity = {};

entity._property = "hello world";
Object.defineProperty(entity, "property", {
    get: function () { return this._property; },
    set: function (value) {
        this._property = value;
    },
    enumerable: true,
    configurable: true
});
Nach dem Login kopieren

Auf diese Weise haben Sie die volle Kontrolle über Lese- und Schreibvorgänge. Das Problem besteht darin, dass auf das _property-Mitglied immer noch direkt zugegriffen und es geändert werden kann.

Aus diesem Grund benötigen wir eine stabilere und zuverlässigere Möglichkeit, private Mitglieder zu deklarieren, auf die über Objektmethoden zugegriffen werden kann.

2. Den Abschlussraum nutzen (Closure Space)

Die Lösung besteht darin, den Abschlussraum zu nutzen. Immer wenn eine innere Funktion aus dem Bereich der äußeren Funktion auf eine Variable zugreift, weist der Browser einen Speicherplatz für Sie zu. Manchmal ist es schwierig, aber für unser Problem ist dies eine perfekte Lösung.

我们在上个代码版本中添加这个特性:
var createProperty = function (obj, prop, currentValue) 
{
    Object.defineProperty(obj, prop, 
    {
            get: function () { return currentValue; },
            set: function (value) {
            currentValue = value;
                    },
                    enumerable: true,
                    configurable: true    });
                    } 
var entity = {}; 
var myVar = "hello world";createProperty(entity, "property", myVar);
Nach dem Login kopieren

Im Beispiel verfügt die Funktion „createProperty“ über eine Variable „currentValue“ und es gibt Get- und Set-Methoden. Diese Variable wird im Abschlussraum der Get- und Set-Funktionen gespeichert. Jetzt können nur diese beiden Funktionen die Variable currentValue sehen und aktualisieren!

Der einzige Vorbehalt, Warnung, Achtung) ist, dass der Quellwert (myVar) weiterhin zugänglich ist. Eine weitere robustere Version (die die Variable myVar schützt) ist unten angegeben:

var createProperty = function (obj, prop) {
    var currentValue = obj[prop];
    Object.defineProperty(obj, prop, {
        get: function () { return currentValue; },
        set: function (value) {
            currentValue = value;
        },
        enumerable: true,
        configurable: true
    });
}

var entity = {
    property: "hello world"
};

createProperty(entity, "property");
Nach dem Login kopieren

Mit dieser Funktion werden sogar die Quellwerte zerstört (zerstört, Hinweis: Dies bedeutet, dass sie nicht direkt zugewiesen werden können ). Sie sind fertig!

3. Überlegungen zur Leistung

Jetzt schauen wir uns die Leistung an.

Offensichtlich ist es im Vergleich zu einer einfachen Variablen, einem Abschlussraum oder sogar einer (Objekt-)Eigenschaft viel langsamer und ressourcenintensiver. Aus diesem Grund konzentriert sich dieser Artikel mehr auf die Unterschiede zwischen gewöhnlichen Methoden und Schließungsraummechanismen.

Um zu beweisen, dass der Closed-Space-Mechanismus nicht mehr Ressourcen verbraucht als die Standardmethode, habe ich den folgenden Code für einen Benchmark-Test geschrieben:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<style>
    html {
        font-family: "Helvetica Neue", Helvetica;
    }
</style>
<body>
    <p id="results">Computing...</p>
    <script>
        var results = document.getElementById("results");
        var sampleSize = 1000000;
        var opCounts = 1000000;

        var entities = [];

        setTimeout(function () {
            // Creating entities
            for (var index = 0; index < sampleSize; index++) {
                entities.push({
                    property: "hello world (" + index + ")"
                });
            }

            // Random reads
            var start = new Date().getTime();
            for (index = 0; index < opCounts; index++) {
                var position = Math.floor(Math.random() * entities.length);
                var temp = entities[position].property;
            }
            var end = new Date().getTime();

            results.innerHTML = "<strong>Results:</strong><br>Using member access: <strong>" + (end - start) + "</strong> ms";
        }, 0);

        setTimeout(function () {
            // Closure space =======================================
            var createProperty = function (obj, prop, currentValue) {
                Object.defineProperty(obj, prop, {
                    get: function () { return currentValue; },
                    set: function (value) {
                        currentValue = value;
                    },
                    enumerable: true,
                    configurable: true
                });
            }
            // Adding property and using closure space to save private value
            for (var index = 0; index < sampleSize; index++) {
                var entity = entities[index];

                var currentValue = entity.property;
                createProperty(entity, "property", currentValue);
            }

            // Random reads
            var start = new Date().getTime();
            for (index = 0; index < opCounts; index++) {
                var position = Math.floor(Math.random() * entities.length);
                var temp = entities[position].property;
            }
            var end = new Date().getTime();

            results.innerHTML += "<br>Using closure space: <strong>" + (end - start) + "</strong> ms";
        }, 0);

        setTimeout(function () {
            // Using local member =======================================
            // Adding property and using local member to save private value
            for (var index = 0; index < sampleSize; index++) {
                var entity = entities[index];

                entity._property = entity.property;
                Object.defineProperty(entity, "property", {
                    get: function () { return this._property; },
                    set: function (value) {
                        this._property = value;
                    },
                    enumerable: true,
                    configurable: true
                });
            }

            // Random reads
            var start = new Date().getTime();
            for (index = 0; index < opCounts; index++) {
                var position = Math.floor(Math.random() * entities.length);
                var temp = entities[position].property;
            }
            var end = new Date().getTime();

            results.innerHTML += "<br>Using local member: <strong>" + (end - start) + "</strong> ms";
        }, 0);

    </script>
</body>
</html>
Nach dem Login kopieren

Ich habe eine Million Objekte erstellt, allesamt welche Property-Mitglieder. Um die folgenden drei Tests abzuschließen:

  • Führen Sie 1 Million Zufallszugriffe auf Attribute durch.

  • Führt 1 Million Random-Access-Closure-Space-Implementierungsversionen durch.

  • Führt 1 Million Zufallszugriffe auf die reguläre Get/Set-Implementierung durch.

Die Testergebnisse sind in den folgenden Tabellen und Diagrammen dargestellt:

Beispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild)Beispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild)

Wir haben festgestellt, dass die Schließraumimplementierung korrekt ist Immer schneller als die herkömmliche Implementierung, je nach Browser, können auch weitere Leistungsoptimierungen vorgenommen werden.

Die Leistung auf Chrome ist geringer als erwartet. Möglicherweise liegt ein Fehler vor. Um dies zu bestätigen, habe ich das Google-Projektteam kontaktiert und die aufgetretenen Symptome beschrieben. Wenn Sie außerdem die Leistung in Microsoft Edge testen möchten – dem neu veröffentlichten Browser von Microsoft, der standardmäßig in Windows 10 installiert ist – können Sie zum Herunterladen klicken.

Wenn Sie jedoch sorgfältig studieren, werden Sie feststellen, dass die Verwendung von Abschlussraum oder Attributen etwa zehnmal länger dauert als der direkte Zugriff auf Variablenelemente. Verwenden Sie es daher angemessen und mit Vorsicht.

Beispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild)

4. Speicherbedarf

Wir müssen auch sicherstellen, dass diese Technologie nicht zu viel Speicher verbraucht. Um den Speichernutzungs-Benchmark zu testen, habe ich das folgende Code-Snippet geschrieben:

Direct attribute reference version (Reference Code)

var sampleSize = 1000000;
 var entities = []; 
// Creating entities
for (var index = 0; index < sampleSize; index++) {
    entities.push({
            property: "hello world (" + index + ")"
});}
Nach dem Login kopieren

Regular Way version (Regular Way, get/set)

var sampleSize = 1000000;

var entities = [];

// Adding property and using local member to save private value
for (var index = 0; index < 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);
}
Nach dem Login kopieren

Closure Space-Version

var sampleSize = 1000000;

var entities = [];

var createProperty = function (obj, prop, currentValue) {
    Object.defineProperty(obj, prop, {
        get: function () { return currentValue; },
        set: function (value) {
            currentValue = value;
        },
        enumerable: true,
        configurable: true
    });
}

// Adding property and using closure space to save private value
for (var index = 0; index < sampleSize; index++) {
    var entity = {};

    var currentValue = "hello world (" + index + ")";
    createProperty(entity, "property", currentValue);

    entities.push(entity);
}
Nach dem Login kopieren

Danach habe ich alle drei Teile des Codes ausgeführt (auf drei großen Browsern) und den eingebetteten Speicherleistungsanalysator gestartet (im Browser wird die F12-Symbolleiste verwendet). dieses Beispiel):

Beispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild)

Die Ergebnisse der Ausführung auf meinem Computer sind wie folgt:

Beispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild)

In Bezug auf den Abschlussraum und herkömmliche Methoden ist die Leistung des Abschlussraums (Speichernutzung) nur bei Chrome etwas besser. Bei IE11 und Firefox steigt die Speichernutzung, aber die Vergleichsergebnisse der Browser sind e-für moderne Browser. Benutzer werden den Unterschied höchstwahrscheinlich nicht bemerken.

Weitere JavaScript-Praktiken

Vielleicht werden Sie überrascht sein, dass Microsoft eine Reihe kostenloser Lernmaterialien zum Thema Open-Source-Javascript bereitgestellt hat und wir eine Aufgabe starten, um weitere Microsoft Edge-Praktiken zu erstellen Serie. Schauen Sie sich meinen Artikel an:

  • Entwickeln von WebGL 3D-Grundlagen basierend auf HTML5 und Babylon.JS

  • Erstellen einer Single-Page-Anwendung basierend auf ASP. NET und AngularJS

  • HTML Advanced Image Technology

Oder unsere Teamserie:

  • HTML/ Anwendungstipps zur JavaScript-Leistungsoptimierung (Diese Serie besteht aus 7 Teilen, vom responsiven Design bis zur Leistungsoptimierung von Gelegenheitsspielen)

  • Schneller Einstieg in moderne Webplattformen (HTML-, CSS- und JS-Grundlagen)

  • Entwickeln Sie universelle Windows-Apps mit HTML und JavaScript, um schnell loszulegen (erstellen Sie Apps mit Ihrem eigenen JS)

und einige kostenlose Tools: Visual Studio-Community, Azure-Testversionen und browserübergreifende Testtools für Mac, Linux oder Windows.

Fazit

Wie Sie sehen, sind Verschlussraumattribute (Mechanismen) eine großartige Möglichkeit, wirklich private Daten zu erstellen. Möglicherweise müssen Sie mit einem geringfügigen Anstieg des Speicherverbrauchs (Problem) rechnen, aber meiner Meinung nach ist dies sehr vernünftig (dieser Preis kann gegen eine höhere Leistungssteigerung im Vergleich zur herkömmlichen Methode eingetauscht werden).

Nebenbei: Wenn Sie es selbst ausprobieren möchten, können Sie den Code hier herunterladen. Empfehlen Sie hier einen guten Artikel mit Anleitungen zu Azure Mobile Services.

Das obige ist der detaillierte Inhalt vonBeispielcode zum Einbetten privater Mitglieder in JavaScript-Objekte (Bild). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage