【问题标题】:Test if object is implementation of interface in Google Closure class framework测试对象是否是 Google Closure 类框架中接口的实现
【发布时间】:2015-01-21 09:46:46
【问题描述】:

如何测试 JavaScript 对象是否是使用 Google Closure inheritance mechanism 的接口的实现?


我在通过new my.Dog()object instanceof my.Animal 创建的对象中找不到任何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

【问题讨论】:

  • 我很想在被否决之前得到一个关于有什么问题的评论。

标签: javascript google-closure-compiler google-closure google-closure-library


【解决方案1】:

@interface 纯粹是一个类型检查器构造。在未编译的代码中,没有任何东西可以检查 cmets 的 @interface/@implements 以添加任何用于运行时检查的接线。 Closure 的目标是代码在编译前后运行相同(假设您遵守所使用的优化模式的限制)。需要运行时检查的典型模式是标记实现您感兴趣的接口的类:

my.Dog.prototype.implements_my_Animal = true;

然后

if (foo.implements_my_Animal) ...

这有点烦人,所以你在不需要的地方看不到它。有多种包装方法,但如果您使用 ADVANCED 模式,大多数会导致实现类(在您的示例中为 my.Dog)转义并且如果未使用则不可移除。

【讨论】:

  • 注意:您可能应该添加一个哨兵对象而不是 true 并检查等价性,例如 (foo.implements_my_Animal === the_object),否则当一个对象碰巧定义了相同的键时,您会得到误报。这很容易在高级编译后发生,将其重命名为foo.a。这是我们在 Clojurescript 中遇到的:dev.clojure.org/jira/browse/CLJS-1658
【解决方案2】:

你不能直接。

在闭包编译器类型系统中,@extends 用于继承并与instanceof 测试相关。 @implements 表示的接口实现严格来说是编译时检查。它们承诺您的对象包含与接口定义相匹配的方法和属性。

因此,要在运行时全面测试它们,您需要检查接口的每个属性的存在性和类型。

【讨论】:

    猜你喜欢
    • 2010-10-20
    • 2010-11-24
    • 1970-01-01
    • 2013-04-07
    • 1970-01-01
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    相关资源
    最近更新 更多