Arbeiten mit Objekten
JavaScript ist auf einem objektbasierten Paradigma aufgebaut. Ein Objekt ist eine Sammlung vonEigenschaften, und eine Eigenschaft ist eine Zuordnung zwischen einem Namen (oderSchlüssel) und einem Wert. Der Wert einer Eigenschaft kann eine Funktion sein, in diesem Fall wird die Eigenschaft alsMethode bezeichnet.
Objekte in JavaScript können, wie auch in vielen anderen Programmiersprachen, mit Objekten im echten Leben verglichen werden. In JavaScript ist ein Objekt eine eigenständige Entität mit Eigenschaften und Typ. Vergleichen Sie es beispielsweise mit einer Tasse. Eine Tasse ist ein Objekt mit Eigenschaften. Eine Tasse hat eine Farbe, ein Design, ein Gewicht, ein Material, aus dem sie hergestellt ist, usw. Auf die gleiche Weise können JavaScript-Objekte Eigenschaften haben, die ihre Merkmale definieren.
Zusätzlich zu den vordefinierten Objekten im Browser können Sie Ihre eigenen Objekte definieren. Dieses Kapitel beschreibt, wie man Objekte, Eigenschaften und Methoden verwendet und wie man eigene Objekte erstellt.
Erstellen neuer Objekte
Sie können ein Objekt mit einemObjektinitialisierer erstellen. Alternativ können Sie zuerst eine Konstrukturfunktion erstellen und dann ein Objekt instanziieren, indem Sie diese Funktion mit demnew
Operator aufrufen.
Verwendung von Objektinitialisierern
Objektinitialisierer werden auch alsObjektliterale bezeichnet. "Objektinitialisierer" ist konsistent mit der Terminologie, die in C++ verwendet wird.
Die Syntax für ein Objekt mit einem Objektinitialisierer ist:
const obj = { property1: value1, // property name may be an identifier 2: value2, // or a number "property n": value3, // or a string};
Jeder Eigenschaftsname vor den Doppelpunkten ist ein Bezeichner (entweder ein Name, eine Zahl oder ein Stringliteral), und jedervalueN
ist ein Ausdruck, dessen Wert dem Eigenschaftsnamen zugewiesen wird. Der Eigenschaftsname kann auch ein Ausdruck sein; berechnete Schlüssel müssen in eckige Klammern eingeschlossen werden. DieObjektinitialisierer Referenz enthält eine ausführlichere Erklärung der Syntax.
In diesem Beispiel wird das neu erstellte Objekt einer Variablenobj
zugewiesen — dies ist optional. Wenn Sie sich nicht anderweitig auf dieses Objekt beziehen müssen, müssen Sie es keiner Variablen zuweisen. (Beachten Sie, dass Sie das Objektliteral möglicherweise in Klammern setzen müssen, wenn das Objekt dort erscheint, wo eine Anweisung erwartet wird, damit das Literal nicht mit einer Blockanweisung verwechselt wird.)
Objektinitialisierer sind Ausdrücke, und jeder Objektinitialisierer führt zu einem neuen Objekt, das immer dann erstellt wird, wenn die Anweisung, in der es erscheint, ausgeführt wird. Identische Objektinitialisierer erzeugen unterschiedliche Objekte, die nicht als gleich verglichen werden.
Die folgende Anweisung erstellt ein Objekt und weist es der Variablenx
zu, wenn und nur wenn der Ausdruckcond
wahr ist:
let x;if (cond) { x = { greeting: "hi there" };}
Das folgende Beispiel erstelltmyHonda
mit drei Eigenschaften. Beachten Sie, dass dieengine
-Eigenschaft auch ein Objekt mit eigenen Eigenschaften ist.
const myHonda = { color: "red", wheels: 4, engine: { cylinders: 4, size: 2.2 },};
Mit Initialisierern erstellte Objekte werden alsgewöhnliche Objekte bezeichnet, weil sie Instanzen vonObject
sind, aber kein anderer Objekttyp. Einige Objekttypen haben spezielle Initialisierer-Syntaxen — zum BeispielArray-Initialisierer undRegex-Literale.
Verwendung einer Konstrukturfunktion
Alternativ können Sie ein Objekt in zwei Schritten erstellen:
- Definieren Sie den Objekttyp durch das Schreiben einer Konstrukturfunktion. Es gibt eine starke Konvention, aus gutem Grund, den Anfangsbuchstaben groß zu schreiben.
- Erstellen Sie eine Instanz des Objekts mit
new
.
Um einen Objekttyp zu definieren, erstellen Sie eine Funktion für den Objekttyp, die seinen Namen, seine Eigenschaften und Methoden spezifiziert. Angenommen, Sie möchten einen Objekttyp für Autos erstellen. Sie möchten, dass dieser ObjekttypCar
genannt wird, und Sie möchten, dass er Eigenschaften für Marke, Modell und Jahr hat. Dazu würden Sie die folgende Funktion schreiben:
function Car(make, model, year) { this.make = make; this.model = model; this.year = year;}
Beachten Sie die Verwendung vonthis
, um Werte basierend auf den an die Funktion übergebenen Werten den Eigenschaften des Objekts zuzuweisen.
Jetzt können Sie ein Objekt namensmyCar
wie folgt erstellen:
const myCar = new Car("Eagle", "Talon TSi", 1993);
Diese Anweisung erstelltmyCar
und weist ihm die angegebenen Werte für seine Eigenschaften zu. Dann ist der Wert vonmyCar.make
der String"Eagle"
,myCar.model
ist der String"Talon TSi"
,myCar.year
ist die Zahl1993
usw. Die Reihenfolge der Argumente und Parameter sollte dieselbe sein.
Sie können jede Anzahl vonCar
-Objekten durch Aufrufe vonnew
erstellen. Zum Beispiel,
const randCar = new Car("Nissan", "300ZX", 1992);const kenCar = new Car("Mazda", "Miata", 1990);
Ein Objekt kann eine Eigenschaft haben, die selbst ein anderes Objekt ist. Zum Beispiel nehmen wir an, Sie definieren ein Objekt namensPerson
wie folgt:
function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex;}
und dann zwei neuePerson
-Objekte wie folgt instanziieren:
const rand = new Person("Rand McKinnon", 33, "M");const ken = new Person("Ken Jones", 39, "M");
Dann können Sie die Definition vonCar
um eineowner
-Eigenschaft erweitern, die einPerson
-Objekt aufnimmt, wie folgt:
function Car(make, model, year, owner) { this.make = make; this.model = model; this.year = year; this.owner = owner;}
Um die neuen Objekte zu instanziieren, verwenden Sie dann Folgendes:
const car1 = new Car("Eagle", "Talon TSi", 1993, rand);const car2 = new Car("Nissan", "300ZX", 1992, ken);
Beachten Sie, dass anstelle eines Literal-Strings oder -Ganzzahlwerts beim Erstellen der neuen Objekte die Objekterand
undken
als Argumente für die Besitzer übergeben werden. Wenn Sie dann den Namen des Besitzers voncar2
herausfinden möchten, können Sie die folgende Eigenschaft zugreifen:
car2.owner.name;
Sie können immer einer vorher definierten Eigenschaft eines Objekts eine Eigenschaft hinzufügen. Zum Beispiel verleiht die Anweisung
car1.color = "black";
einecolor
-Eigenschaft zucar1
und weist ihr den Wert"black"
zu. Dies betrifft jedoch keine anderen Objekte. Um die neue Eigenschaft zu allen Objekten des gleichen Typs hinzuzufügen, müssen Sie die Eigenschaft zur Definition desCar
-Objekttyps hinzufügen.
Sie können auch dieclass
Syntax anstelle derfunction
-Syntax verwenden, um eine Konstrukturfunktion zu definieren. Weitere Informationen finden Sie imKlassen-Leitfaden.
Verwendung der Object.create()-Methode
Objekte können auch mit der MethodeObject.create()
erstellt werden. Diese Methode kann sehr nützlich sein, denn sie erlaubt Ihnen, das gewünschtePrototypen-Objekt für das zu erstellende Objekt auszuwählen, ohne eine Konstrukturfunktion zu definieren.
// Animal properties and method encapsulationconst Animal = { type: "Invertebrates", // Default value of properties displayType() { // Method which will display type of Animal console.log(this.type); },};// Create new animal type called animal1const animal1 = Object.create(Animal);animal1.displayType(); // Logs: Invertebrates// Create new animal type called fishconst fish = Object.create(Animal);fish.type = "Fishes";fish.displayType(); // Logs: Fishes
Objekte und Eigenschaften
Ein JavaScript-Objekt hat damit verbundene Eigenschaften. Objekt-Eigenschaften sind im Grunde dasselbe wie Variablen, außer dass sie Objekten und nichtScopes zugeordnet sind. Die Eigenschaften eines Objekts definieren die Charakteristika des Objekts.
Zum Beispiel erzeugt das folgende Beispiel ein Objekt namensmyCar
, mit Eigenschaften namensmake
,model
undyear
, mit den Werten"Ford"
,"Mustang"
und1969
:
const myCar = { make: "Ford", model: "Mustang", year: 1969,};
Wie JavaScript-Variablen, sind Eigenschaftsnamen case-sensitive. Eigenschaftsnamen können nur Strings oder Symbole sein — alle Schlüssel werdenin Strings umgewandelt, es sei denn, sie sind Symbole.Array-Indizes sind tatsächlich Eigenschaften mit String-Schlüsseln, die ganze Zahlen enthalten.
Zugriff auf Eigenschaften
Sie können auf eine Eigenschaft eines Objekts über den Eigenschaftsnamen zugreifen.Eigenschafts-Accessoren kommen in zwei Syntaxen:Punktnotation undKlammernotation. Zum Beispiel könnten Sie auf die Eigenschaften desmyCar
-Objekts wie folgt zugreifen:
// Dot notationmyCar.make = "Ford";myCar.model = "Mustang";myCar.year = 1969;// Bracket notationmyCar["make"] = "Ford";myCar["model"] = "Mustang";myCar["year"] = 1969;
Ein Objekt-Eigenschaftsname kann jeder JavaScript-String oderSymbol sein, einschließlich eines leeren Strings. Sie können jedoch nicht die Punktnotation verwenden, um eine Eigenschaft zuzugreifen, deren Name kein gültiger JavaScript-Bezeichner ist. Zum Beispiel kann ein Eigenschaftsname, der ein Leerzeichen oder einen Bindestrich enthält, mit einer Zahl beginnt oder in einer Variablen gehalten wird, nur mit der Klammernotation aufgerufen werden. Diese Notation ist auch sehr nützlich, wenn Eigenschaftsnamen zur Laufzeit dynamisch bestimmt werden sollen, d.h. nicht vorhersagbar bis zur Laufzeit. Beispiele sind wie folgt:
const myObj = {};const str = "myString";const rand = Math.random();const anotherObj = {};// Create additional properties on myObjmyObj.type = "Dot syntax for a key named type";myObj["date created"] = "This key has a space";myObj[str] = "This key is in variable str";myObj[rand] = "A random number is the key here";myObj[anotherObj] = "This key is object anotherObj";myObj[""] = "This key is an empty string";console.log(myObj);// {// type: 'Dot syntax for a key named type',// 'date created': 'This key has a space',// myString: 'This key is in variable str',// '0.6398914448618778': 'A random number is the key here',// '[object Object]': 'This key is object anotherObj',// '': 'This key is an empty string'// }console.log(myObj.myString); // 'This key is in variable str'
Im obigen Code ist der SchlüsselanotherObj
ein Objekt, das weder ein String noch ein Symbol ist. Wenn es zummyObj
hinzugefügt wird, ruft JavaScript dietoString()
Methode vonanotherObj
auf und verwendet den resultierenden String als neuen Schlüssel.
Sie können auch auf Eigenschaften mit einem String-Wert zugreifen, der in einer Variablen gespeichert ist. Die Variable muss in der Klammernotation übergeben werden. Im obigen Beispiel hielt die Variablestr
den Wert"myString"
und es ist"myString"
, das der Eigenschaftsname ist. Daher gibtmyObj.str
als undefined zurück.
str = "myString";myObj[str] = "This key is in variable str";console.log(myObj.str); // undefinedconsole.log(myObj[str]); // 'This key is in variable str'console.log(myObj.myString); // 'This key is in variable str'
Dies ermöglicht den Zugriff auf jede Eigenschaft, wie zur Laufzeit bestimmt:
let propertyName = "make";myCar[propertyName] = "Ford";// access different properties by changing the contents of the variablepropertyName = "model";myCar[propertyName] = "Mustang";console.log(myCar); // { make: 'Ford', model: 'Mustang' }
Achtung! Die Verwendung von eckigen Klammern für den Zugriff auf Eigenschaften, deren Namen durch externe Eingaben bereitgestellt werden, kann Ihren Code anfällig fürObjektinjektionsangriffe machen.
Nicht vorhandene Eigenschaften eines Objekts haben den Wertundefined
(und nichtnull
).
myCar.nonexistentProperty; // undefined
Aufzählen von Eigenschaften
Es gibt drei native Wege zur Auflistung/Traversierung von Objekteigenschaften:
for...in
Schleifen. Diese Methode durchläuft alle aufzählbaren String-Eigenschaften eines Objekts sowie dessen Prototypkette.Object.keys()
. Diese Methode gibt ein Array mit nur den aufzählbaren eigenen String-Eigenschaftsnamen ("Schlüsseln") im ObjektmyObj
zurück, jedoch nicht jene in der Prototypkette.Object.getOwnPropertyNames()
. Diese Methode gibt ein Array zurück, das alle eigenen String-Eigenschaftsnamen im ObjektmyObj
enthält, unabhängig davon, ob sie aufzählbar sind oder nicht.
Sie können die Klammer-Notation mitfor...in
verwenden, um über alle aufzählbaren Eigenschaften eines Objekts zu iterieren. Um zu veranschaulichen, wie dies funktioniert, zeigt die folgende Funktion die Eigenschaften des Objekts an, wenn Sie das Objekt und den Namen des Objekts als Argumente an die Funktion übergeben:
function showProps(obj, objName) { let result = ""; for (const i in obj) { // Object.hasOwn() is used to exclude properties from the object's // prototype chain and only show "own properties" if (Object.hasOwn(obj, i)) { result += `${objName}.${i} = ${obj[i]}\n`; } } console.log(result);}
Der Begriff "eigene Eigenschaft" bezieht sich auf die Eigenschaften des Objekts, jedoch ohne die der Prototypkette. Daher würde der FunktionsaufrufshowProps(myCar, 'myCar')
folgendes ausgeben:
myCar.make = FordmyCar.model = MustangmyCar.year = 1969
Das Obige ist äquivalent zu:
function showProps(obj, objName) { let result = ""; Object.keys(obj).forEach((i) => { result += `${objName}.${i} = ${obj[i]}\n`; }); console.log(result);}
Es gibt keinen nativen Weg, um geerbte nicht aufzählbare Eigenschaften aufzulisten. Dies kann jedoch mit der folgenden Funktion erreicht werden:
function listAllProperties(myObj) { let objectToInspect = myObj; let result = []; while (objectToInspect !== null) { result = result.concat(Object.getOwnPropertyNames(objectToInspect)); objectToInspect = Object.getPrototypeOf(objectToInspect); } return result;}
Weitere Informationen finden Sie unterAufzählbarkeit und Eigentümerschaft von Eigenschaften.
Löschen von Eigenschaften
Sie können eine nicht geerbte Eigenschaft mit demdelete
-Operator entfernen. Der folgende Code zeigt, wie eine Eigenschaft entfernt wird.
// Creates a new object, myObj, with two properties, a and b.const myObj = { a: 5, b: 12 };// Removes the a property, leaving myObj with only the b property.delete myObj.a;console.log("a" in myObj); // false
Vererbung
Alle Objekte in JavaScript erben von mindestens einem anderen Objekt. Das Objekt, von dem geerbt wird, wird als Prototyp bezeichnet, und die geerbten Eigenschaften können imprototype
-Objekt des Konstruktors gefunden werden. Weitere Informationen finden Sie unterVererbung und die Prototypenkette.
Definition von Eigenschaften für alle Objekte eines Typs
Sie können eine Eigenschaft zu allen durch einen bestimmtenKonstruktor erstellten Objekten hinzufügen, indem Sie dieprototype
-Eigenschaft verwenden. Dies definiert eine Eigenschaft, die von allen Objekten des angegebenen Typs geteilt wird und nicht nur von einer Instanz des Objekts. Der folgende Code fügt allen Objekten des TypsCar
einecolor
-Eigenschaft hinzu und liest dann den Eigenschaftswert von einer Instanzcar1
.
Car.prototype.color = "red";console.log(car1.color); // "red"
Methoden definieren
EineMethode ist eine Funktion, die mit einem Objekt verknüpft ist, oder anders ausgedrückt, eine Methode ist eine Eigenschaft eines Objekts, die eine Funktion ist. Methoden werden auf die gleiche Weise definiert, wie normale Funktionen definiert werden, außer dass sie als Eigenschaft eines Objekts zugewiesen werden müssen. Siehe auchMethodendefinitionen für weitere Details. Ein Beispiel ist:
objectName.methodName = functionName;const myObj = { myMethod: function (params) { // do something }, // this works too! myOtherMethod(params) { // do something else },};
woobjectName
ein bestehendes Objekt ist,methodName
der Name ist, den Sie der Methode zuweisen, undfunctionName
der Name der Funktion.
Sie können dann die Methode im Kontext des Objekts wie folgt aufrufen:
objectName.methodName(params);
Methoden werden typischerweise auf demprototype
-Objekt des Konstruktors definiert, sodass alle Objekte desselben Typs die gleiche Methode teilen. Zum Beispiel können Sie eine Funktion definieren, die die Eigenschaften der zuvor definiertenCar
-Objekte formatiert und anzeigt.
Car.prototype.displayCar = function () { const result = `A Beautiful ${this.year} ${this.make} ${this.model}`; console.log(result);};
Beachten Sie die Verwendung vonthis
, um auf das Objekt zu verweisen, zu dem die Methode gehört. Dann können Sie diedisplayCar
-Methode für jedes der Objekte wie folgt aufrufen:
car1.displayCar();car2.displayCar();
Die Verwendung von this für Objektverweise
JavaScript hat ein spezielles Schlüsselwort,this
, das Sie innerhalb einer Methode verwenden können, um auf das aktuelle Objekt zu verweisen. Zum Beispiel, nehmen wir an, Sie haben 2 Objekte,Manager
undIntern
. Jedes Objekt hat seinen eigenenname
,age
undjob
. In der FunktionsayHi()
, beachten Sie die Verwendung vonthis.name
. Wenn die Funktion zu den 2 Objekten hinzugefügt wird, druckt die gleiche Funktion die Nachricht mit dem Namen des jeweiligen Objekts, dem es zugeordnet ist.
const Manager = { name: "Karina", age: 27, job: "Software Engineer",};const Intern = { name: "Tyrone", age: 21, job: "Software Engineer Intern",};function sayHi() { console.log(`Hello, my name is ${this.name}`);}// add sayHi function to both objectsManager.sayHi = sayHi;Intern.sayHi = sayHi;Manager.sayHi(); // Hello, my name is KarinaIntern.sayHi(); // Hello, my name is Tyrone
this
ist ein "versteckter Parameter" eines Funktionsaufrufs, der übergeben wird, indem das Objekt vor der Funktion angegeben wird, die aufgerufen wurde. Zum Beispiel, inManager.sayHi()
, istthis
dasManager
-Objekt, weilManager
vor der FunktionsayHi()
kommt. Wenn Sie auf dieselbe Funktion von einem anderen Objekt aus zugreifen, ändert sichthis
ebenfalls. Wenn Sie andere Methoden verwenden, um die Funktion wieFunction.prototype.call()
oderReflect.apply()
aufzurufen, können Sie den Wert vonthis
explizit als Argument übergeben.
Definition von Gettern und Settern
EinGetter ist eine Funktion, die mit einer Eigenschaft verknüpft ist, die den Wert einer bestimmten Eigenschaft erhält. EinSetter ist eine Funktion, die mit einer Eigenschaft verknüpft ist, die den Wert einer bestimmten Eigenschaft setzt. Zusammen können sie den Wert einer Eigenschaft indirekt darstellen.
Getter und Setter können entweder
- innerhalb vonObjektinitialisierern definiert werden oder
- später zu einem bestehenden Objekt hinzugefügt werden.
Innerhalb vonObjektinitialisierern werden Getter und Setter wie reguläreMethoden definiert, jedoch mit den Schlüsselwörternget
oderset
davor. Die Getter-Methode darf keinen Parameter erwarten, während die Setter-Methode genau einen Parameter erwartet (den neuen zu setzenden Wert). Zum Beispiel:
const myObj = { a: 7, get b() { return this.a + 1; }, set c(x) { this.a = x / 2; },};console.log(myObj.a); // 7console.log(myObj.b); // 8, returned from the get b() methodmyObj.c = 50; // Calls the set c(x) methodconsole.log(myObj.a); // 25
Die Eigenschaften des ObjektsmyObj
sind:
myObj.a
— eine ZahlmyObj.b
— ein Getter, dermyObj.a
plus 1 zurückgibtmyObj.c
— ein Setter, der den Wert vonmyObj.a
auf die Hälfte des Wertes setzt, auf denmyObj.c
gesetzt wird
Getter und Setter können auch zu einem Objekt jederzeit nach der Erstellung mit der MethodeObject.defineProperties()
hinzugefügt werden. Der erste Parameter dieser Methode ist das Objekt, auf das sie den Getter oder Setter definieren möchten. Der zweite Parameter ist ein Objekt, dessen Eigenschaftsnamen die Namen der Getter oder Setter sind und dessen Eigenschaftswerte Objekte sind, um die Getter- oder Setterfunktionen zu definieren. Hier ist ein Beispiel, das den gleichen Getter und Setter wie im vorherigen Beispiel definiert:
const myObj = { a: 0 };Object.defineProperties(myObj, { b: { get() { return this.a + 1; }, }, c: { set(x) { this.a = x / 2; }, },});myObj.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' propertyconsole.log(myObj.b); // Runs the getter, which yields a + 1 or 6
Welche der beiden Formen Sie wählen sollten, hängt von Ihrem Programmierstil und der aktuellen Aufgabe ab. Wenn Sie die Definition des ursprünglichen Objekts ändern können, werden Sie wahrscheinlich Getter und Setter durch den ursprünglichen Initialisierer definieren. Diese Form ist kompakter und natürlicher. Wenn Sie jedoch später Getter und Setter hinzufügen müssen — vielleicht weil Sie das spezifische Objekt nicht geschrieben haben — dann ist die zweite Form die einzige mögliche Form. Die zweite Form repräsentiert besser die dynamische Natur von JavaScript, kann aber den Code schwer lesbar und verständlich machen.
Vergleich von Objekten
In JavaScript sind Objekte ein Referenztyp. Zwei unterschiedliche Objekte sind niemals gleich, selbst wenn sie die gleichen Eigenschaften haben. Nur der Vergleich des gleichen Objektverweises mit sich selbst ergibt wahr.
// Two variables, two distinct objects with the same propertiesconst fruit = { name: "apple" };const anotherFruit = { name: "apple" };fruit == anotherFruit; // return falsefruit === anotherFruit; // return false
// Two variables, a single objectconst fruit = { name: "apple" };const anotherFruit = fruit; // Assign fruit object reference to anotherFruit// Here fruit and anotherFruit are pointing to same objectfruit == anotherFruit; // return truefruit === anotherFruit; // return truefruit.name = "grape";console.log(anotherFruit); // { name: "grape" }; not { name: "apple" }
Weitere Informationen über Vergleichsoperatoren finden Sie unterGleichheitsoperatoren.
Siehe auch
MDN-Feedback-Box
Diese Seite wurde automatisch aus dem Englischen übersetzt.