Ich sah mich nach der Object.defineProperty
Methode um, konnte aber nichts Anständiges finden.
Jemand hat mir diesen Codeausschnitt gegeben :
Object.defineProperty(player, "health", {
get: function () {
return 10 + ( player.level * 15 );
}
})
Aber ich verstehe es nicht. Hauptsächlich ist das get
das, was ich nicht bekommen kann (Wortspiel beabsichtigt). Wie funktioniert es?
javascript
object
defineproperty
Mathekühler
quelle
quelle
Antworten:
Da Sie eine ähnliche Frage gestellt haben , gehen wir Schritt für Schritt vor. Es ist etwas länger, aber es kann Ihnen viel mehr Zeit sparen, als ich für das Schreiben aufgewendet habe:
Property ist eine OOP-Funktion zur sauberen Trennung von Client-Code. In einigen E-Shops gibt es beispielsweise folgende Objekte:
In Ihrem Kundencode (dem E-Shop) können Sie Ihren Produkten Rabatte hinzufügen:
Später kann der E-Shop-Besitzer feststellen, dass der Rabatt nicht größer als 80% sein kann. Jetzt müssen Sie JEDES Auftreten der Rabattänderung im Kundencode finden und eine Zeile hinzufügen
Dann kann der E-Shop-Besitzer seine Strategie weiter ändern, z. B. "Wenn der Kunde Wiederverkäufer ist, kann der maximale Rabatt 90% betragen" . Und Sie müssen die Änderung an mehreren Stellen erneut vornehmen und daran denken, diese Zeilen jedes Mal zu ändern, wenn die Strategie geändert wird. Das ist ein schlechtes Design. Deshalb ist die Kapselung das Grundprinzip von OOP. Wenn der Konstruktor so wäre:
Dann können Sie einfach die Methoden
getDiscount
( Accessor ) undsetDiscount
( Mutator ) ändern . Das Problem ist, dass sich die meisten Mitglieder wie gemeinsame Variablen verhalten, nur der Rabatt bedarf hier besonderer Sorgfalt. Für ein gutes Design muss jedoch jedes Datenelement gekapselt werden, damit der Code erweiterbar bleibt. Sie müssen also viel Code hinzufügen, der nichts bewirkt. Dies ist auch ein schlechtes Design, ein Boilerplate Antipattern . Manchmal können Sie die Felder nicht einfach später in Methoden umgestalten (der Eshop-Code wird möglicherweise größer oder ein Code von Drittanbietern hängt von der alten Version ab), sodass das Boilerplate hier weniger böse ist. Trotzdem ist es böse. Aus diesem Grund wurden Eigenschaften in viele Sprachen eingeführt. Sie können den ursprünglichen Code beibehalten, indem Sie einfach das Rabattmitglied in eine Eigenschaft mit umwandelnget
undset
Blöcke:Beachten Sie die vorletzte Zeile: Die Verantwortung für den korrekten Rabattwert wurde vom Kundencode (E-Shop-Definition) in die Produktdefinition verschoben. Das Produkt ist dafür verantwortlich, dass seine Datenmitglieder konsistent bleiben. Gutes Design ist (grob gesagt), wenn der Code genauso funktioniert wie unsere Gedanken.
Soviel zu Eigenschaften. Javascript unterscheidet sich jedoch von reinen objektorientierten Sprachen wie C # und codiert die Funktionen unterschiedlich:
In C # ist die Umwandlung von Feldern in Eigenschaften eine wichtige Änderung . Daher sollten öffentliche Felder als automatisch implementierte Eigenschaften codiert werden, wenn Ihr Code möglicherweise in einem separat kompilierten Client verwendet wird.
In Javascript werden die Standardeigenschaften (Datenelement mit Getter und Setter, wie oben beschrieben) durch den Accessor-Deskriptor (in dem Link, den Sie in Ihrer Frage haben) definiert. Exklusiv können Sie verwenden Daten Descriptor (so dass Sie nicht verwenden können , dh Wert und Satz auf dem gleichen Grundstück):
Beide Deskriptoren können folgende Mitglieder haben:
for(var i in theObject)
. Wenn false, wird es nicht iteriert, ist aber weiterhin als öffentlich zugänglich* außer im strengen Modus - in diesem Fall stoppt JS die Ausführung mit TypeError, es sei denn, es wird im Try-Catch-Block abgefangen
Verwenden Sie zum Lesen dieser Einstellungen
Object.getOwnPropertyDescriptor()
.Lernen Sie anhand eines Beispiels:
Wenn Sie dem Client-Code solche Cheats nicht erlauben möchten, können Sie das Objekt um drei Begrenzungsstufen einschränken:
Object.isExtensible(<yourObject>)
dieseOption, um zu überprüfen, ob die Methode für das Objekt verwendet wurde. Die Prävention ist flach (siehe unten).configurable: false
auf alle Eigenschaften festgelegt). Verwenden SieObject.isSealed(<yourObject>)
dieseOption, um diese Funktion am Objekt zu erkennen. Das Siegel ist flach (siehe unten).writable: false
alle Eigenschaften mit Datendeskriptor festgelegt ). Die beschreibbare Eigenschaft von Setter ist nicht betroffen (da sie keine hat). Das Einfrieren ist flach : Wenn die Eigenschaft Objekt ist, werden ihre Eigenschaften NICHT eingefroren (wenn Sie möchten, sollten Sie so etwas wie "Deep Freeze" ausführen, ähnlich wie beim Deep Copy-Klonen ). Verwenden SieObject.isFrozen(<yourObject>)
, um es zu erkennen.Sie müssen sich nicht darum kümmern, wenn Sie nur ein paar Zeilen schreiben, die Spaß machen. Aber wenn Sie ein Spiel codieren möchten (wie Sie in der verknüpften Frage erwähnt haben), sollten Sie sich wirklich um gutes Design kümmern. Versuchen Sie, etwas über google Antipatterns und Codegeruch . Es wird Ihnen helfen, Situationen wie "Oh, ich muss meinen Code komplett neu schreiben!" Zu vermeiden. Es kann Ihnen Monate der Verzweiflung ersparen, wenn Sie viel codieren möchten. Viel Glück.
quelle
function Product(name,price) { this.name = name; this.price = price; var _discount; // private member Object.defineProperty(this,"discount",{ get: function() { return _discount; }, set: function(value) { _discount = value; if(_discount>80) _discount = 80; } }); } var sneakers = new Product("Sneakers",20); sneakers.discount = 50; // 50, setter is called sneakers.discount+= 20; // 70, setter is called sneakers.discount+= 20; // 80, not 90! alert(sneakers.discount); // getter is called
get
ist eine Funktion, die aufgerufen wird, wenn Sie versuchen, den Wert zu lesenplayer.health
, wie in:Es ist effektiv nicht viel anders als:
Das Gegenteil von get wird gesetzt, das verwendet wird, wenn Sie dem Wert zuweisen. Da es keinen Setter gibt, scheint es nicht beabsichtigt zu sein, der Gesundheit des Spielers zuzuweisen:
Ein sehr einfaches Beispiel:
quelle
()
zum Aufrufen verwenden müssen ... Ich verstehe nicht, was die Idee war, als sie dieses Ding erfunden haben. Die Funktionen sind völlig gleich: jsbin.com/bugipi/edit?js,console,outputdefineProperty ist eine Methode für Object, mit der Sie die Eigenschaften so konfigurieren können, dass sie einige Kriterien erfüllen. Hier ist ein einfaches Beispiel mit einem Mitarbeiterobjekt mit zwei Eigenschaften firstName & lastName. Fügen Sie die beiden Eigenschaften hinzu, indem Sie die toString- Methode für das Objekt überschreiben .
Sie erhalten die Ausgabe als: Jameel Moideen
Ich werde den gleichen Code ändern, indem ich defineProperty für das Objekt verwende
Der erste Parameter ist der Name des Objekts und der zweite Parameter ist der Name der Eigenschaft, die wir hinzufügen. In unserem Fall ist es toString. Der letzte Parameter ist ein json-Objekt, dessen Wert eine Funktion sein wird, und drei Parameter, die beschreibbar und aufzählbar sind und jetzt konfigurierbar. Ich habe gerade alles als wahr deklariert.
Wenn Sie das Beispiel ausführen, erhalten Sie die Ausgabe als: Jameel Moideen
Lassen Sie uns verstehen, warum wir die drei Eigenschaften wie beschreibbar, aufzählbar und konfigurierbar benötigen .
schreibbar
Einer der sehr ärgerlichen Teile des Javascript ist, wenn Sie beispielsweise die Eigenschaft toString in etwas anderes ändern
Wenn Sie dies erneut ausführen, wird alles unterbrochen. Lassen Sie uns beschreibbar in falsch ändern. Wenn Sie dasselbe erneut ausführen, erhalten Sie die korrekte Ausgabe als 'Jameel Moideen'. Diese Eigenschaft verhindert, dass diese Eigenschaft später überschrieben wird.
aufzählbar
Wenn Sie alle Schlüssel im Objekt drucken, werden alle Eigenschaften einschließlich toString angezeigt.
Wenn Sie enumerable auf false setzen, können Sie die Eigenschaft toString vor allen anderen ausblenden. Wenn Sie dies erneut ausführen, erhalten Sie Vorname, Nachname
konfigurierbar
Wenn jemand das Objekt später neu definiert, z. B. auf true aufzählbar, und es ausführen kann. Sie können sehen, dass die toString-Eigenschaft erneut verfügbar ist.
Sie können dieses Verhalten einschränken, indem Sie configure auf false setzen.
Der ursprüngliche Verweis auf diese Informationen stammt aus meinem persönlichen Blog
quelle
Grundsätzlich
defineProperty
handelt es sich um eine Methode, die drei Parameter berücksichtigt - ein Objekt, eine Eigenschaft und einen Deskriptor. Was in diesem speziellen Aufruf passiert, ist, dass die"health"
Eigenschaft desplayer
Objekts dem 10-fachen des 15-fachen Levels des Spielerobjekts zugewiesen wird.quelle
ja nein weitere funktionserweiterung für setup setter & getter dies ist mein beispiel Object.defineProperty (obj, name, func)
quelle
Object.defineProperty () ist eine globale Funktion. Sie ist nicht in der Funktion verfügbar, die das Objekt anderweitig deklariert. Sie müssen es statisch verwenden ...
quelle
Zusammenfassung:
Object.defineProperty
wird verwendet, um eine neue Eigenschaft für das Player-Objekt zu erstellen.Object.defineProperty
ist eine Funktion, die nativ in der JS-Laufzeitumgebung vorhanden ist und die folgenden Argumente akzeptiert:Object.defineProperty(obj, prop, descriptor)
Das Deskriptorobjekt ist der interessante Teil. Hier können wir folgende Dinge definieren:
<boolean>
: Wenntrue
der Eigenschaftsdeskriptor geändert und die Eigenschaft aus dem Objekt gelöscht werden kann. Wenn konfigurierbar, könnenfalse
die übergebenen DeskriptoreigenschaftenObject.defineProperty
nicht geändert werden.<boolean>
: Wenntrue
die Eigenschaft mit dem Zuweisungsoperator überschrieben werden kann.<boolean>
: Wenntrue
die Eigenschaft in einerfor...in
Schleife wiederholt werden kann. Auch bei Verwendung derObject.keys
Funktion ist die Taste vorhanden. Wenn die Eigenschaft ist, werdenfalse
sie nicht mit einerfor..in
Schleife durchlaufen und bei der Verwendung nicht angezeigtObject.keys
.<function>
: Eine Funktion, die immer dann aufgerufen wird, wenn die Eigenschaft erforderlich ist. Anstatt den direkten Wert anzugeben, wird diese Funktion aufgerufen und der zurückgegebene Wert als Wert der Eigenschaft angegeben<function>
: Eine Funktion, die immer dann aufgerufen wird, wenn die Eigenschaft zugewiesen ist. Anstatt den direkten Wert festzulegen, wird diese Funktion aufgerufen und der zurückgegebene Wert wird verwendet, um den Wert der Eigenschaft festzulegen.Beispiel:
quelle
quelle
Definiert eine neue Eigenschaft direkt für ein Objekt oder ändert eine vorhandene Eigenschaft für ein Objekt und gibt das Objekt zurück.
Einfache Erklärung zum Definieren von Eigenschaften.
Beispielcode: https://jsfiddle.net/manoj_antony32/pu5n61fs/
quelle
quelle