Zum Hauptinhalt springen




Sicherheit ist ein Thema, das nicht leicht genommen werden sollte. Anfänger können mit einigen dieser Sicherheitstechniken in nicht vertraut sein JavaScript, e incluso uno que otro Programmierer experimentado puede que también ignore estas prácticas. Sin embargo, mas allá de la importancia de conocer estos métodos es praticarlos día a día en nuestra Programmierung.

Projekteigenschaften wurden traditionell in JavaScript ungeschützt gelassen oder ausgeblendet und in einem Abschluss erfasst. Symbole und WeakMaps bieten eine weitere Alternative.

Sowohl Chrome (Version 36) als auch Firefox (Version 31) unterstützen WeakMaps. Chrome 36 unterstützt Symbole, Sie müssen jedoch experimentelles JavaScript in aktivieren chrome://flags/#enable-javascript-harmony. Firefox unterstützt Symbole der Version 33.

Ungeschütztes Szenario

Instanzen der Person Mit der folgenden Funktion erstellt, werden Eigenschaften direkt darin gespeichert.

var Person = (function () {function Person (name) {this.name = name;} Person.prototype.getName = function () {return this.name;}; return Person;} ()); var p = neue Person ('John'); print ('Name von Person 1:' + p.getName ()); p.name löschen; print ('Name von Person 1:' + p.getName () + '- außerhalb geändert.');

Dieser Ansatz hat den Vorteil, dass alle Instanzen der Person Sie sind ähnlich und der Zugriff auf die Eigenschaften dieser Instanzen kann optimiert werden. Andererseits gibt es hier keine privaten Immobilien - Alle Objekteigenschaften können geändert werden durch externen Code (in diesem Fall - gelöscht).

Einige Bibliotheken bevorzugen es, Eigenschaften, die privat sein sollen, den Unterstrich voranzustellen (z. B. _Name).

Andere - als TypeScript - dependen del Compiler para marcar todos los usos ilegales de una propiedad privada.

Eigenschaften mit Verschlüssen ausblenden

Um eine Eigenschaft von einer externen Änderung zu isolieren, können Sie einen internen Abschluss verwenden, der über dem Fenster geschlossen wird Variablennamen. Die Douglas Crockford-Codekonventionen für JavaScript empfehlen dieses Muster, wenn der Datenschutz wichtig ist, um die Eigenschaften von Namen mit dem Unterstrichpräfix zu bestimmen, um den Datenschutz anzuzeigen.

var Person = (function () {function Person (name) {this.getName = function () {return name;};} return person;} ()); var p = neue Person ('John'); print ('Name von Person 2:' + p.getName ()); p.name löschen; print ('Name von Person 2:' + p.getName () + 'bleibt privat.');

Der Abschlussansatz hat den Vorteil einer echten Privatsphäre, aber die Kosten bestehen darin, dass für jede Instanz einer Person ein neuer Abschluss erstellt werden muss (die Funktion innerhalb des Konstruktors des Person).

Verwendung von Symbolen

Mit ES6 gibt es noch eine Möglichkeit, Eigenschaften zu speichern: Symbole.

Symbole ähneln privaten Namen, bieten jedoch im Gegensatz zu privaten Namen keine echte Privatsphäre.

Para ejecutar el ejemplo que ves tu Browser debe soportar:

var Person = (function () {var nameSymbol = Symbol ('name'); function Person (name) {this [nameSymbol] = name;} Person.prototype.getName = function () {return this [nameSymbol];}; return Person;} ()); var p = neue Person ('John'); print ('Name von Person 3:' + p.getName ()); p.name löschen; print ('Name von Person 3:' + p.getName () + '- bleibt privat.'); print ('Eigenschaften von Person 3:' + Object.getOwnPropertyNames (p));

Symbole erhöhen nicht die Anzahl der Abschlüsse für jede erstellte Instanz. Es gibt nur einen Verschluss, um das Symbol zu schützen.

Symbole werden zum Indizieren von JavaScript-Objekten verwendet. Der Hauptunterschied zu anderen Typen besteht darin, dass sie nicht in Zeichenfolgen konvertiert und von verfügbar gemacht werden Object.getOwnPropertyNames. Nur mit dem Referenzsymbol können Sie Werte für das Objekt festlegen und abrufen. Mit der Funktion kann auf eine Liste von Symbolen zugegriffen werden, die einem bestimmten Objekt zugewiesen sind Object.getOwnPropertySymbols.

Jedes Symbol ist einzigartig, auch wenn es mit derselben Bezeichnung erstellt wurde.

ES6-Symbole ✅

var sym1 = Symbol ('a'); var sym2 = Symbol ('b'); var sym3 = Symbol ('a'); print ('sym1 === sym1:' + (sym1 === sym1)); print ('sym1 === sym2:' + (sym1 === sym2)); print ('sym1 === sym3:' + (sym1 === sym3));

Symbole haben folgende Nachteile:

  • Höhere Komplexität bei der Handhabung von Symbolen - Anstelle eines einfachen p.-Namens müssen Sie zuerst die Symbolreferenz abrufen und dann verwenden p [nameSymbol].
  • Actualmente sólo unos pocos Browser soportan símbolos.
  • No garantizan una verdadera privacidad, pero pueden utilizarse para separar las propiedades públicas de las internas de los objetos. Es similar a cómo la mayoría de los lenguajes orientados a objetos permiten el acceso a propiedades privadas a través de la API de reflexión.

Private Symbole werden für ECMAScript weiterhin berücksichtigt, aber die richtige Implementierung, bei der Symbole niemals gefiltert werden, ist schwierig. Private Symbole werden bereits von der ES6-Spezifikation verwendet und intern in V8 implementiert.

Verwenden von WeakMaps

Ein weiterer Ansatz zum Speichern privater Immobilien ist WeakMaps.

Eine WeakMap-Instanz ist in einem Abschluss versteckt und wird durch Instanzen von indiziert Person. Kartenwerte sind Objekte, die private Daten enthalten.

var Person = (function () {var private = new WeakMap (); function Person (name) {var privateProperties = {name: name}; private.set (this, privateProperties);} Person.prototype.getName = function () {return private.get (this) .name;}; return Person;} ()); var p = neue Person ('John'); print ('Name von Person 4:' + p.getName ()); p.name löschen; print ('Name von Person 4:' + p.getName () + '- bleibt privat.'); print ('Eigenschaften von Person 4:' + Object.getOwnPropertyNames (p));

Es ist möglich, Map anstelle einer WeakMap oder sogar einiger Arrays zu verwenden, um diese Lösung nachzuahmen. Die Verwendung von WeakMap hat jedoch einen erheblichen Vorteil: Dadurch können Personeninstanzen mit Müll gesammelt werden.

Eine Karte oder eine Matrix enthält Objekte, die stark enthalten. Person Es ist ein Abschluss, der die private Variable erfasst - was auch eine starke Referenz ist. Der Garbage Collector kann ein Objekt erfassen, wenn nur schwache Verweise darauf vorhanden sind (oder wenn überhaupt keine Verweise vorhanden sind). Aufgrund der beiden starken Referenzen, solange die Funktion Person Sein alcanzable desde las raíces de la CG, entonces cada instancia de Person jamás creada es alcanzable y por lo tanto no puede ser recolectada como basura.

Die WeakMap hält die Schlüssel schwach und das macht sowohl die Personeninstanz als auch ihre privaten Daten für die Speicherbereinigung eines Objekts geeignet Person Der Rest der Anwendung verweist nicht mehr darauf.

Zugriff auf Eigenschaften anderer Instanzen

Alle vorgestellten Lösungen (mit Ausnahme der Verschlüsse) weisen ein interessantes Merkmal auf. Instanzen können auf private Eigenschaften anderer Instanzen zugreifen.

Das folgende Beispiel klassifiziert die Instanzen von Person mit ihren Namen. Die Funktion vergleichen mit verwendet die privaten Daten dieser und anderer Instanzen.

var Person = (function () {var private = new WeakMap (); function Person (name) {var privateProperties = {name: name}; private.set (this, privateProperties);} Person.prototype.compareTo = function (other ) {var thisName = private.get (this) .name; var otherName = private.get (other) .name; return thisName.localeCompare (otherName);}; Person.prototype.toString = function () {return private.get (this) .name;}; return Person;} ()); var people = [neue Person ('John'), neue Person ('Jane'), neue Person ('Jim')]; people.sort (Funktion (erste, zweite) {return first.compareTo (zweite);}); print ('Sortierte Personen:' + people.join (','));

Das gleiche Beispiel in Java geschrieben:

import java.util.Arrays; Klasse Person implementiert Vergleichbar {privater Stringname; öffentliche Person (String name) {this.name = name; } public int compareTo (Person other) {return this.name.compareTo (other.name); } public String toString () {return this.name; }} public class Main {public statisch final void main (String ... args) {Person [] people = neue Person [] {neue Person ("John"), neue Person ("Jane"), neue Person ("Jim" ")}; Arrays.sort (Personen); System.out.print ("Sortierte Personen:" + Arrays.toString (Personen)); }}

Die Methode Person :: compareTo Verwendet den privaten Feldnamen dieser Instanz und eines anderen Objekts.

Felicidades por haber finalizado este nuevo tutorial, recuerda que en tu Netz schoolJavaScript.com tendrás acceso a los mejores cursos de Programmiersprache JavaScript.