Проверьте, является ли объект реализацией интерфейса в каркасе класса Google Closure

Как я могу проверить, является ли объект JavaScript реализацией интерфейса, использующего механизм наследования Google Closure?


Я не мог найти ни намека на my.Animal в объектах, созданных с помощью new my.Dog() а также object instanceof my.Animal не работал Единственная информация об интерфейсе - это ошибки компилятора при забвении реализации методов в дочернем классе.

/**
 * @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

Один из способов, который я нашел, - это приблизительное тестирование свойств интерфейсов, хотя это очень плохо во многих аспектах:

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

2 ответа

Решение

@interface это просто конструкция проверки типа. В не скомпилированном коде нет ничего, что могло бы проверить комментарии для @interface/@implements добавить любую проводку для проверки во время выполнения. Целью Closure является то, что код будет выполняться одинаково до и после компиляции (при условии, что вы соблюдаете ограничение для используемого вами режима оптимизации). Типичным шаблоном, когда требуется проверка во время выполнения, является тег класса, который реализует интересующий вас интерфейс:

my.Dog.prototype.implements_my_Animal = true;

затем

if (foo.implements_my_Animal) ...

Это немного раздражает, поэтому вы не видите его там, где это не нужно. Есть несколько способов обернуть это, но если вы используете режим ADVANCED, большинство из них приводит к тому, что реализующий класс (my.Dog в вашем примере) экранируется и не удаляется, если не используется.

Вы не можете напрямую.

В системе типов Closure-compiler, @extends используется для наследования и соотносится с instanceof тесты. Реализации интерфейса, обозначенные @implements строго проверка времени компиляции. Они обещают, что ваш объект содержит методы и свойства, которые соответствуют определениям интерфейса.

Таким образом, для их комплексного тестирования во время выполнения вам необходимо проверить наличие и тип каждого свойства интерфейса.

Другие вопросы по тегам