Zum Hauptinhalt springen

Sicherheit ist ein Thema, das nicht leicht genommen werden sollte. Anfänger sind möglicherweise mit einigen dieser JavaScript-Sicherheitstechniken nicht vertraut, und selbst ein erfahrener Programmierer kennt diese Praktiken möglicherweise nicht. Über die Wichtigkeit, diese Methoden zu kennen, hinaus ist es jedoch wichtig, sie Tag für Tag in unserer Programmierung zu üben.

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 - Sie sind darauf angewiesen, dass der Compiler alle illegalen Verwendungen von Privateigentum kennzeichnet.

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.

Um das angezeigte Beispiel auszuführen, muss Ihr Browser Folgendes unterstützen:

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].
  • Derzeit unterstützen nur wenige Browser Symbole.
  • Sie garantieren keine echte Privatsphäre, können jedoch verwendet werden, um öffentliche und interne Eigenschaften von Objekten zu trennen. Es ähnelt der Art und Weise, wie die meisten objektorientierten Sprachen den Zugriff auf private Eigenschaften über die Reflection-API ermöglichen.

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 ist von den CG-Wurzeln aus erreichbar, dann ist jede jemals erstellte Personeninstanz erreichbar und kann daher nicht durch Müll gesammelt werden.

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.

Herzlichen Glückwunsch zum Abschluss dieses neuen Tutorials. Denken Sie daran, dass dies auf Ihrer Website der Fall ist schoolJavaScript.com Sie haben Zugriff auf die besten JavaScript-Programmiersprachenkurse.

R Marketing Digital