2017-06-27 1 views
0

Wie kann ich (zur Laufzeit) prüfen, ob ein unbekanntes Objekt ein bestimmter Typ ist? Und dann formell zu diesem Typ konvertieren und etwas damit machen?Überprüfen Sie, ob ein Objekt ein Google Closure-Typ ist, und konvertieren Sie es?

Ich mag so etwas wie dies zu tun:

const /** {Object} */ someObject = {name: 'Apple', color: 'Red'}; 
if (someObject is Fruit) { 
    // Convert to {Fruit} and do something with it. 
    return /** {Fruit} */ (someObject); 
} 

wo Fruit ist eine Klasse mit dem Namen Eigenschaften und Farbe.

Um genauer zu sein, kann ich nicht einfach ein Fruit Objekt mit einem Konstruktor erstellen, wie ich das Objekt von JSON.parse bekomme.

Bisher habe ich versucht:

if (someObject instanceof Fruit) 

dies falsch gelöst. Und ich habe versucht:

const aFruit = /** @type {Fruit} */ someObj; 

Aber dies scheint nicht wirklich etwas zu tun .. das heißt, wenn ich in someObj übergeben, die nicht Eigenschaften Namen hat oder Farbe es immer noch als Fruit behandelt wird.

Vielleicht brauche ich eine komplexere/benutzerdefinierte Lösung? Dh ist das in Closure eingebaut oder soll ich die Attribute einfach selbst überprüfen?

+1

Verschlusstypen existieren nur bei der Kompilierung. – SLaks

+0

Mit einigen zusätzlichen Erklärungen, wie Typ Converting '/ ** @type {Fruit} * /' funktioniert/warum es hier nicht funktioniert, würde ich akzeptieren "Sie können nicht; tun dies allein" als Antwort . – hubatish

+0

Der 'instanceof'-Test funktioniert nur, wenn das Objekt mit' new' erstellt wird (oder wenn die JavaScript 'property'-Werte manuell angeordnet werden). Können Sie aus den Eigenschaften heraus testen, um welchen Objekttyp es sich handelt? Wenn dies der Fall ist, können Sie das Typ-Casting verwenden, wie Sie es in Ihrem ersten Beispiel gezeigt haben. – owler

Antwort

0

instanceof ist, was Sie suchen. So überprüfen Sie, ob ein bestimmter Wert aus einer bestimmten Konstruktorfunktion (oder besser ES2015-Klasse) erstellt wurde.

const /** {Object} */ someObject = new Fruit('Apple', 'red'); 
if (someObject instanceof Fruit) { 
    // Convert to {Fruit} and do something with it. 
    return /** {Fruit} */ (someObject); 
} 

In Ihrem ursprünglichen Beispiel, was macht ein Objekt zu einer Frucht? Sie verwenden anonyme Objekte. Ist ein Objekt, das eine name und color Eigenschaft hat, eine Frucht? Dies ist ein wenig unklar und sehr implementierungsspezifisch. Sie müssen in der Lage sein, sich selbst zu beantworten "Was macht ein Objekt zur Frucht?"

Wenn Sie überprüfen wollen, ob ein Objekt ein Obst-Schnittstelle implementiert (hat die richtigen Eigenschaften), überprüfen Sie einfach für diese Eigenschaften:

/** 
* @param {!Object} obj 
* @return {boolean} 
*/ 
function isFruit(obj) { 
    return obj.color && obj.name; 
} 
-1

Das Typsystem von Closure existiert nur zur Kompilierzeit.

Genau wie in C sagen die Modelle einfach das Typsystem "Ich garantiere, dass dieser Wert tatsächlich von diesem Typ ist, auch wenn Sie es nicht beweisen können".
Wenn das nicht stimmt, erhalten Sie undefiniertes Verhalten (besonders bei erweiterten Optimierungen).

+0

Dies ist nicht streng zutreffend. Die meisten Typen basieren auf Konstruktoren oder Schnittstellen. Beide können zur Laufzeit überprüft werden. –

+0

@ChadKillingsworth: Schnittstellen können nicht sein. – SLaks

+0

Sicher können sie - eine Schnittstelle ist nur eine Reihe von Eigenschaften. Wenn ein Objekt Eigenschaften aufweist, die den bestimmten Typen entsprechen, können diese zur Laufzeit überprüft werden. –

Verwandte Themen