5

Jak mogę sprawdzić, czy obiekt JavaScript jest implementacją interfejsu przy użyciu Google Closure inheritance mechanism?Sprawdź, czy obiekt jest implementacją interfejsu w klasie klasy zamknięcia Google


nie mogłem znaleźć żadnego śladu my.Animal w obiektach stworzonych przez new my.Dog() i object instanceof my.Animal nie działa. Jedyną informacją na temat interfejsu są błędy kompilatora, gdy zapomniano zaimplementować metody w klasie potomnej.

/** 
* @interface 
*/ 
my.Animal = function() {}; 

/** 
* Does something. 
* @return {string} 
*/ 
my.Animal.prototype.doSomething; 

/** 
* @constructor 
* @implements {my.Animal} 
*/ 
my.Dog = function() {}; 

/** @inheritDoc */ 
my.Dog.prototype.doSomething() = function { 
    return "something"; 
} 

var dog = new my.Dog(); 
console.log(dog instanceof my.Animal); // returns false 

Jednym ze sposobów, znalazłem to w przybliżeniu test właściwości interfejsów, mimo że jest źle w tak wielu aspektach:

console.log(!!dog.doSomething); // returns true 
+2

Chciałbym uzyskać komentarz na temat tego, co jest nie tak, PRZED obniżeniem ceny. –

Odpowiedz

2

@interface jest wyłącznie konstrukcją sprawdzającą typ. W nieskompilowanym kodzie nie ma nic, co mogłoby sprawdzić komentarze pod kątem dodania okablowania do sprawdzania w czasie wykonywania. Celem zamknięcia jest to, że kod będzie działał tak samo przed i po kompilacji (zakładając, że zaobserwujesz ograniczenie dla trybu optymalizacji, którego używasz). Typowy wzór gdy pożądane jest sprawdzenie Runtime jest oznaczyć klasy, która implementuje interfejs, który cię interesuje:

my.Dog.prototype.implements_my_Animal = true; 

następnie

if (foo.implements_my_Animal) ... 

jest to nieco irytujące, więc nie widzę gdzie to nie jest potrzebne. Istnieje wiele sposobów na owijanie tego, ale jeśli korzystasz z trybu ADVANCED, większość wyników w klasie implementacji (my.Dog w twoim przykładzie) ucieka i nie jest wymienna, jeśli nie jest używana.

+0

Uwaga: Powinieneś raczej dodać obiekt wartownika zamiast wartości true i sprawdzić równoważność, np. '(Foo.implements_my_Animal === the_object)' ponieważ w przeciwnym razie otrzymasz fałszywe alarmy, gdy zdarzy się, że obiekt zdefiniuje ten sam klucz. To może się łatwo zdarzyć po wcześniejszej kompilacji, która zmienia jej nazwę na "foo.a". To jest coś, co napotkaliśmy w Clojurescript: https://dev.clojure.org/jira/browse/CLJS-1658 – ClojureMostly

1

Państwo bezpośrednio nie da.

W systemie typu kompilator zamknięcia, @extends jest używany do dziedziczenia i koreluje z testami instanceof. Implementacje interfejsu oznaczone przez @implements są ściśle kontrolowane w czasie kompilacji. Są obietnicą, że twój obiekt zawiera metody i właściwości, które pasują do definicji interfejsu.

Jako takie, aby przetestować je w czasie wykonywania w sposób kompleksowy, należy sprawdzić, czy istnieją i typ każdej właściwości interfejsu.

Powiązane problemy