um neue Eigenschaften für ein Objekt zu erstellen. Ich bin mir bewusst, dass ich Dinge wie einstellen kann
enumerable: false
aber wann braucht man das wirklich? Wenn Sie nur eine Eigenschaft wie festlegen
myObject.myprop = 5;
seine Deskriptoren sind alle auf true gesetzt, richtig? Ich bin eigentlich eher neugierig, wann Sie diesen ziemlich ausführlichen Aufruf von .defineProperty() verwenden und aus welchen Gründen.
Rob W
Object.defineProperty wird hauptsächlich verwendet, um Eigenschaften mit bestimmten Eigenschaftsdeskriptoren festzulegen (z. B. schreibgeschützt (Konstanten), Aufzählbarkeit (um eine Eigenschaft in einer for (.. in ..) Schleife, Getter, Setter).
"use strict";
var myObj = {}; // Create object
// Set property (+descriptor)
Object.defineProperty(myObj, 'myprop', {
value: 5,
writable: false
});
console.log(myObj.myprop);// 5
myObj.myprop = 1; // In strict mode: TypeError: myObj.myprop is read-only
Beispiel
Diese Methode erweitert die Object Prototyp mit einer Eigenschaft. Nur der Getter ist definiert und die Aufzählbarkeit ist auf gesetzt false.
OK das verstehe ich. Aber ist das sinnvoll? Meistens möchte ich, dass alle Deskriptoren auf wahr gesetzt sind, damit ich die Eigenschaften einfach auf die altmodische Weise einrichten kann, oder? Gibt es noch andere Vorteile für .defineProperty?
– André Meinhold
11. April 2012 um 12:29 Uhr
@RobW: Sie können auch erstellen getters und setters ohne zu benutzen .defineProperty.
– jAndy
11. April 2012 um 12:40 Uhr
@jAndy Aber die Eigenschaft wird in a angezeigt for (.. in ..) Schleife: Object.prototype.__defineGetter__('lol',function(){return 3});for(var i in [])alert(i); zeigt an "lol". Object.defineProperty kann verwendet werden, um einen Getter/Setter zu definieren, der Auch tut nicht zeige dich ein for (.. in ..) Schleifen.
– Rob W
11. April 2012 um 12:45 Uhr
@RobW: Ich habe mehr über die Verwendung nachgedacht var foo = { get lol() { return 5;} };aber das Problem bleibt das gleiche.
– jAndy
11. April 2012 um 12:48 Uhr
@Andre: Wenn du keinen Anwendungsfall für sie siehst, dann brauchst du sie nicht … wenn du sie brauchst, wirst du es wissen 😉
– Felix Klinge
11. April 2012 um 12:56 Uhr
Pascalius
Features wie ‘enumerable’ werden meiner Erfahrung nach selten genutzt. Der Hauptanwendungsfall sind berechnete Eigenschaften:
Es scheint mir, als würden Sie sich alle Mühe geben, dies im Namen einer sehr grauen Zone in der Semantik zu einer Eigenschaft zu machen.
– aaaaa
12. Januar 2015 um 14:49 Uhr
@aaaaa was? graue Zone?
– Pascalius
12. Januar 2015 um 14:57 Uhr
Ich verstehe einfach nicht den Anwendungsfall, eine berechnete Eigenschaft bereitzustellen, anstatt sie einfach zu einer Funktion zu machen. zB myObj.area = function() { return this.width * this.height; }
– aaaaa
12. Januar 2015 um 22:46 Uhr
Die Funktion ist vollständig gültig, aber es kann Anwendungsfälle geben, in denen Sie eine Eigenschaft einer Funktion vorziehen.
– Pascalius
13. Januar 2015 um 10:26 Uhr
Die primäre Verwendung wäre, dass Sie, anstatt zwei separate Funktionen (z. B.: getFoo(), setFoo()) zu haben, eine einzelne Eigenschaft mit einem Getter / Setter definieren können, der benutzerdefinierte Logik umschließt, und dann einfach Standardzuweisungsoperatoren für eine einzelne verwenden können Mitglied (z. B. x = myObj.Foo oder myObj.Foo = x). Dies macht Ihren Code einfacher und ist auch nützlich, wenn Sie verhindern möchten, dass beim Serialisieren in JSON ein Wert ausgegeben wird. (z. B.: Ihr Objekt hat eine Reihe von UI-spezifischen Eigenschaften, die Sie nicht über die Leitung senden möchten …) Alles in allem hilft dies JS dabei, den Standard-OO-Prinzipien besser zu folgen
– Joshua Barker
29. Juli 2015 um 22:28 Uhr
Ein wirklich guter Grund für die Verwendung von Object.defineProperty ist, dass Sie damit eine Funktion in einem Objekt als berechnete Eigenschaft durchlaufen können, die die Funktion ausführt, anstatt den Hauptteil der Funktion zurückzugeben.
Zum Beispiel:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
Object.defineProperty(myObj, 'area', {
get: function() {
return this.width*this.height;
},
enumerable: true
});
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
//width -> 20, height -> 20, area -> 400
Im Gegensatz zum Hinzufügen der Funktion als Eigenschaft zu einem Objektliteral:
var myObj = {};
myObj.width = 20;
myObj.height = 20;
myObj.area = function() {
return this.width*this.height;
};
for (var key in myObj) {
if (myObj.hasOwnProperty(key)) {
console.log(key + " -> " + myObj[key]);
}
}
// width -> 20, height -> 20, area -> function() { return this.width*this.height;}
Stellen Sie sicher, dass Sie die Enumerable-Eigenschaft auf true setzen, um sie zu durchlaufen.
Wenn Sie ein einfaches JavaScript-Objekt an eine Vue-Instanz als its data Option durchläuft Vue alle seine Eigenschaften und konvertiert sie in getter/setters verwenden Object.defineProperty. Dies ist eine Funktion nur für ES5 und nicht shimmbar, weshalb Vue IE8 und darunter nicht unterstützt.
Die Getter/Setter sind für den Benutzer unsichtbar, aber unter der Haube ermöglichen sie Vue, eine Abhängigkeitsverfolgung und Änderungsbenachrichtigung durchzuführen, wenn auf Eigenschaften zugegriffen oder diese geändert werden.
[…]
Denken Sie daran, dass selbst eine superschlanke und einfache Version von Vue.js etwas mehr als nur verwenden würde Object.definePropertyaber die Hauptfunktionalität kommt davon:
In Javascript sind Objekte Sammlungen von Schlüssel-Wert-Paaren. Object.defineProperty() ist eine Funktion, die eine neue Eigenschaft für ein Objekt definieren und die folgenden Attribute einer Eigenschaft festlegen kann:
Wert <any>: Der dem Schlüssel zugeordnete Wert
schreibbar <boolean>: wenn beschreibbar eingestellt ist true Die Eigenschaft kann aktualisiert werden, indem ihr ein neuer Wert zugewiesen wird. Wenn eingestellt false Sie können den Wert nicht ändern.
aufzählbar <boolean>: wenn enumerable auf gesetzt ist true Auf das Eigentum kann über a zugegriffen werden for..in Schleife. Weiterhin werden nur die aufzählbaren Eigenschaftsschlüssel mit zurückgegeben Object.keys()
konfigurierbar <boolean>: Wenn konfigurierbar auf eingestellt ist false Sie können die Eigenschaftsattribute (Wert/beschreibbar/aufzählbar/konfigurierbar) nicht ändern, auch da Sie den Wert nicht ändern können, können Sie ihn nicht mit löschen delete Operator.
Beispiel:
let obj = {};
Object.defineProperty(obj, 'prop1', {
value: 1,
writable: false,
enumerable: false,
configurable: false
}); // create a new property (key=prop1, value=1)
Object.defineProperty(obj, 'prop2', {
value: 2,
writable: true,
enumerable: true,
configurable: true
}); // create a new property (key=prop2, value=2)
console.log(obj.prop1, obj.prop2); // both props exists
for(const props in obj) {
console.log(props);
// only logs prop2 because writable is true in prop2 and false in prop1
}
obj.prop1 = 100;
obj.prop2 = 100;
console.log(obj.prop1, obj.prop2);
// only prop2 is changed because prop2 is writable, prop1 is not
delete obj.prop1;
delete obj.prop2;
console.log(obj.prop1, obj.prop2);
// only prop2 is deleted because prop2 is configurable and prop1 is not
Tim Ogilvy
Object.definePropertyverhindert, dass Sie versehentlich einem Schlüssel in seiner Prototypkette Werte zuweisen. Mit dieser Methode weisen Sie nur dieser bestimmten Objektebene zu (nicht irgendeinem Schlüssel in der Prototypenkette).
Zum Beispiel: Es gibt ein Objekt wie {key1: value1, key2: value2} und Sie kennen die Prototypkette nicht genau oder Sie verpassen sie versehentlich und es gibt irgendwo in der Prototypkette eine Eigenschaft “Farbe”.
Verwendung von Punkt (.) Zuweisung-
Diese Operation weist dem Schlüssel „Farbe“ in der Prototypkette einen Wert zu(falls Schlüssel irgendwo vorhanden) und Sie finden das Objekt unverändert als . obj.color=”blau”; // obj bleibt dasselbe wie {key1: value1, key2: value2}
// jetzt sieht obj aus wie {key1: value1, key2: value2, color: 'blue'}. Es fügt der gleichen Ebene eine Eigenschaft hinzu. Dann können Sie sicher mit der Methode iterieren Object.hasOwnProperty().
Ein netter Anwendungsfall, den ich gesehen habe defineProperty ist für Bibliotheken, dem Benutzer eine Fehlereigenschaft bereitzustellen, auf die Sie den Fehler selbst protokollieren würden, wenn nicht innerhalb eines bestimmten Intervalls darauf zugegriffen wird. Zum Beispiel: