Wie kann ich feststellen, ob ein Objekt x
hat eine definierte Eigenschaft y
unabhängig vom Wert von x.y
?
Ich verwende derzeit
if (typeof(x.y) !== 'undefined')
aber das scheint ein bisschen klobig zu sein. Gibt es einen besseren Weg?
Wie kann ich feststellen, ob ein Objekt x
hat eine definierte Eigenschaft y
unabhängig vom Wert von x.y
?
Ich verwende derzeit
if (typeof(x.y) !== 'undefined')
aber das scheint ein bisschen klobig zu sein. Gibt es einen besseren Weg?
enthält
Object.keys(x).includes('y');
Die Array.prototype.includes()
bestimmt, ob ein Array einen bestimmten Wert enthält, und gibt je nach Fall true oder false zurück.
と
Object.keys()
gibt ein Array von Strings zurück, die alle aufzählbaren Eigenschaften des angegebenen Objekts darstellen.
.hasOwnProperty()
und die ES6+ ?.
-optionale Verkettung wie: if (x?.y)
sind ebenfalls sehr gute Optionen für 2020+.
Zusätzlich zu den anderen Antworten möchte ich vorschlagen, die Object.hasOwn()
Methode zur Überprüfung, ob das angegebene Objekt die angegebene Eigenschaft als eigene Eigenschaft hat (d.h. auf dem Objekt selbst), können Sie die neue Object.hasOwn()
die eine statische Methode ist, die true zurückgibt, wenn das angegebene Objekt die angegebene Eigenschaft als eigene Eigenschaft hat. Ist die Eigenschaft geerbt oder existiert sie nicht, gibt die Methode false zurück.
const person = { name: 'dan' };
console.log(Object.hasOwn(person, 'name'));// true
console.log(Object.hasOwn(person, 'age'));// false
const person2 = Object.create({gender: 'male'});
console.log(Object.hasOwn(person2, 'gender'));// false
Es wird empfohlen, diese Methode über die Object.hasOwnProperty()
weil es auch für Objekte funktioniert, die mit Hilfe von Object.create(null)
und für Objekte, die die geerbte hasOwnProperty()
Methode. Obwohl es möglich ist, diese Art von Problemen zu lösen, indem man Object.prototype.hasOwnProperty()
auf ein externes Objekt, Object.hasOwn()
diese Probleme zu überwinden, wird daher bevorzugt (siehe Beispiele unten)
let person = {
hasOwnProperty: function() {
return false;
},
age: 35
};
if (Object.hasOwn(person, 'age')) {
console.log(person.age); // true - the remplementation of hasOwnProperty() did not affect the Object
}
let person = Object.create(null);
person.age = 35;
if (Object.hasOwn(person, 'age')) {
console.log(person.age); // true - works regardless of how the object was created
}
Mehr über Object.hasOwn
finden Sie hier: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn
Browser-Kompatibilität - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility
Die Überprüfung, ob die angegebene Eigenschaft auf dem Objekt selbst oder weiter oben in der Prototypenkette existiert, könnte über die in
Operator, wie in anderen Antworten vorgeschlagen.
Da Frage war in Bezug auf Klobigkeit der Eigenschaft Überprüfung, und eine regelmäßige Usecase für die Validierung von Funktion Argument Optionen Objekte, dachte ich, ich würde erwähnen, eine Bibliothek-freie kurze Weise der Prüfung der Existenz von mehreren Eigenschaften. Disclaimer: Es erfordert ECMAScript 5 (aber IMO jeder, der noch IE8 verwendet, verdient ein kaputtes Web).
function f(opts) {
if(!["req1","req2"].every(opts.hasOwnProperty, opts)) {
throw new Error("IllegalArgumentException");
}
alert("ok");
}
f({req1: 123}); // error
f({req1: 123, req2: 456}); // ok
Im Gegensatz zu anderen Beispielen in diesem Thread wird in dieser Implementierung nur behauptet, dass das Objekt eine Eigenschaft hat, auf die wir prüfen wollen.
const hasOwnProperty = <X extends {}, Y extends PropertyKey>(
object: X,
property: Y
): object is Record<Y, unknown> & X => {
return object.hasOwnProperty(property);
};
Hier ein Beispiel, wie ein Zweig mit der gewünschten Eigenschaft identifiziert werden kann.
const hasOwnProperty = <X extends {}, Y extends PropertyKey>(
object: X,
property: Y
): object is Record<Y, unknown> & X => {
return object.hasOwnProperty(property);
};
type PaidProjectFeeType = 'FIXED_PRICE' | 'RATE' | '%future added value';
const PAID_PROJECT_FEE_TYPE_LABELS: Record<
'FIXED_PRICE' | 'RATE',
string
> = {
FIXED_PRICE: 'Fixed Price',
RATE: 'Rate',
};
export const getPaidProjectFeeTypeLabel = (
feeType: PaidProjectFeeType
): string => {
if (hasOwnProperty(PAID_PROJECT_FEE_TYPE_LABELS, feeType)) {
PAID_PROJECT_FEE_TYPE_LABELS[feeType];
}
throw new Error('test');
};
Der Haken an der Sache ist, dass nun PAID_PROJECT_FEE_TYPE_LABELS
angenommen wird:
Record<PaidProjectFeeType, unknown> & Record<"FIXED_PRICE" | "RATE", string>
d.h. Sie können das Ergebnis nicht zurückgeben, weil ein möglicher Wert von X[Y]
es unknown
. Dies ist nützlich, wenn Sie behaupten müssen, dass ein Objekt eine gewünschte Eigenschaft hat, aber Sie müssen weitere Behauptungen hinzufügen, um sicherzustellen, dass das Ergebnis Ihren Vorstellungen entspricht.
Es gibt jedoch einen besseren Weg.
Wir brauchen zwei Versorgungsunternehmen:
export const keys = <T extends Record<string, unknown>>(
object: T
): Array<keyof T> => {
return Object.keys(object);
};
keys
gibt uns ein typisiertes Array von Objekteigenschaftsnamen.
export const includes = <C extends M, M>(
collection: readonly C[],
member: M
): member is C => {
return collection.includes(member as C);
};
includes
erlaubt es zu behaupten, dass eine Eigenschaft Mitglied eines schreibgeschützten Arrays ist. Sie können mehr über Includes in diesem Artikel lesen Blogbeitrag .
export const keys = <T extends Record<string, unknown>>(
object: T
): Array<keyof T> => {
return Object.keys(object);
};
export const includes = <C extends M, M>(
collection: readonly C[],
member: M
): member is C => {
return collection.includes(member as C);
};
type PaidProjectFeeType = 'FIXED_PRICE' | 'RATE' | '%future added value';
const PAID_PROJECT_FEE_TYPE_LABELS: Record<
'FIXED_PRICE' | 'RATE',
string
> = {
FIXED_PRICE: 'Fixed Price',
RATE: 'Rate',
};
export const getPaidProjectFeeTypeLabel = (
feeType: PaidProjectFeeType
): string => {
if (includes(keys(PAID_PROJECT_FEE_TYPE_LABELS), feeType)) {
return PAID_PROJECT_FEE_TYPE_LABELS[feeType];
}
throw new Error('test');
};
Kurz gesagt, dieser Ansatz ermöglicht es uns, die feeType
Wert zu den Werten in keys(PAID_PROJECT_FEE_TYPE_LABELS)
die uns dann den Zugriff auf den Eigenschaftswert ermöglicht.
Dieser Ansatz funktioniert am besten, allerdings mit dem Vorbehalt, dass technisch keys
Implementierung ist nicht laufzeitsicher. Es gibt ein (meist theoretisches) Szenario, in dem die zur Laufzeit zurückgegebenen Werte sich von den mit tsc abgeleiteten unterscheiden.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.