Signatur
Beschreibung
Der in-Operator liefert true, wenn die angegebene Eigenschaft im angegebenen Objekt oder seiner prototype chain enthalten ist.
Der in-Operator kann nicht dazu verwendet werden, in anderen Collections nach Werten zu suchen. Um zu prüfen, ob ein bestimmter Wert in einem Array existiert, verwende Array.prototype.includes(). Für Sets verwende Set.prototype.has().
Der in-Operator prüft, ob eine string- oder symbol-Eigenschaft in einem Objekt oder seiner prototype chain vorhanden ist. Wenn du nur nach nicht geerbten Eigenschaften prüfen möchtest, verwende stattdessen Object.hasOwn().
Eine Eigenschaft kann in einem Objekt vorhanden sein, aber den Wert undefined haben. Daher ist "x" in obj nicht dasselbe wie obj.x !== undefined. Damit in nach dem Hinzufügen einer Eigenschaft false zurückgibt, verwende den delete-Operator, anstatt den Wert der Eigenschaft auf undefined zu setzen.
Du kannst den in-Operator auch verwenden, um zu prüfen, ob ein bestimmtes privates Klassenfeld oder eine private Methode in einem Objekt definiert wurde. Der Operator liefert true, wenn die Eigenschaft definiert ist, andernfalls false. Dies wird als branded check bezeichnet, weil er genau dann true zurückgibt, wenn das Objekt mit diesem Klassen-constructor erzeugt wurde, wonach du auch sicher auf andere private Elemente zugreifen kannst.
Dies ist eine spezielle Syntax — die linke Seite des in-Operators ist ein Property-Identifier statt einer Expression, aber ohne Anführungszeichen (weil es sonst eine string-Eigenschaft wäre und kein privates Element).
Da der Zugriff auf private Elemente auf Objekten, die nicht zur aktuellen Klasse gehören, einen TypeError wirft, anstatt undefined zurückzugeben, erlaubt diese Syntax, folgendes zu verkürzen:
Sie vermeidet außerdem generell die Notwendigkeit, sich mit Error-Handling zu befassen, nur um auf ein möglicherweise nicht vorhandenes privates Element zuzugreifen.
Allerdings erfordert der in-Operator dennoch, dass das private Element zuvor in der umschließenden Klasse deklariert wurde — andernfalls würde er einen SyntaxError werfen ("Private field '#x' must be declared in an enclosing class"), denselben wie beim Versuch, auf ein nicht deklariertes privates Element zuzugreifen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $prop Pflicht | string | symbol | — | Ein string oder symbol, der einen Property-Namen repräsentiert (Nicht-Symbole werden zu Strings gecoerct). Kann auch ein Private-Element-Identifier sein. |
| $object Pflicht | Object | — | Objekt, bei dem geprüft wird, ob es (oder seine prototype chain) die Eigenschaft mit dem angegebenen Namen (prop) enthält. |
Rückgabewert
Beispiele
Grundlegende Verwendung
// Arrays
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
0 in trees; // returns true
3 in trees; // returns true
6 in trees; // returns false
"bay" in trees; // returns false (you must specify the index number, not the value at that index)
"length" in trees; // returns true (length is an Array property)
Symbol.iterator in trees; // returns true
// Predefined objects
"PI" in Math; // returns true
// Custom objects
const myCar = { make: "Honda", model: "Accord", year: 1998 };
"make" in myCar; // returns true
"model" in myCar; // returns true
Objekt auf der rechten Seite erforderlich
const color1 = new String("green");
"length" in color1; // returns true
const color2 = "coral";
// generates an error (color2 is not a String object)
"length" in color2;
Verwendung von in mit gelöschten oder undefined-Eigenschaften
const myCar = { make: "Honda", model: "Accord", year: 1998 };
delete myCar.make;
"make" in myCar; // returns false
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
delete trees[3];
3 in trees; // returns false
Auf undefined gesetzte Eigenschaft
const myCar = { make: "Honda", model: "Accord", year: 1998 };
myCar.make = undefined;
"make" in myCar; // returns true
Array-Element auf undefined gesetzt
const trees = ["redwood", "bay", "cedar", "oak", "maple"];
trees[3] = undefined;
3 in trees; // returns true
Leere Array-Slots
const empties = new Array(3);
empties[2]; // returns undefined
2 in empties; // returns false
Array mit Werten füllen
const empties = new Array(3).fill(undefined);
2 in empties; // returns true
Geerbte Eigenschaften
const ages = { alice: 18, bob: 27 };
function hasPerson(name) {
return name in ages;
}
hasPerson("hasOwnProperty"); // true
Object.hasOwn() verwenden
const ages = { alice: 18, bob: 27 };
function hasPerson(name) {
return Object.hasOwn(ages, name);
}
hasPerson("hasOwnProperty"); // false
Map als Alternative
const ages = new Map([
["alice", 18],
["bob", 27],
]);
function hasPerson(name) {
return ages.has(name);
}
hasPerson("hasOwnProperty"); // false
in-Operator für branded checks
class Person {
#age;
constructor(age) {
this.#age = age;
}
static isPerson(o) {
return #age in o;
}
ageDifference(other) {
return this.#age - other.#age;
}
}
const p1 = new Person(20);
const p2 = new Person(30);
console.log(p1.ageDifference(p2)); // -10
console.log(Person.isPerson(p1)); // true
if (Person.isPerson(p1) && Person.isPerson(p2)) {
console.log(p1.ageDifference(p2)); // -10
}
Fehlerfall ohne branded check
const p2 = {};
p1.ageDifference(p2); // TypeError: Cannot read private member #age from an object whose class did not declare it
Branded check via Symbol.hasInstance
class Person {
#age;
constructor(age) {
this.#age = age;
}
static [Symbol.hasInstance](o) {
// Testing `this` to prevent false-positives when
// calling `instanceof SubclassOfPerson`
return this === Person && #age in o;
}
ageDifference(other) {
return this.#age - other.#age;
}
}
const p1 = new Person(20);
const p2 = new Person(30);
if (p1 instanceof Person && p2 instanceof Person) {
console.log(p1.ageDifference(p2)); // -10
}
try/catch-Verkürzung mit in
class C {
#x;
static isC(obj) {
try {
obj.#x;
return true;
} catch {
return false;
}
}
}
Kurzform mit in
class C {
#x;
static isC(obj) {
return #x in obj;
}
}
SyntaxError bei nicht deklariertem privatem Feld
class C {
foo() {
#x in this;
}
}
new C().foo(); // SyntaxError: Private field '#x' must be declared in an enclosing class