Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将接口实现传递到google closure javascript库中的函数_Javascript_Google Closure Compiler_Google Closure_Google Closure Library - Fatal编程技术网

如何将接口实现传递到google closure javascript库中的函数

如何将接口实现传递到google closure javascript库中的函数,javascript,google-closure-compiler,google-closure,google-closure-library,Javascript,Google Closure Compiler,Google Closure,Google Closure Library,我想定义一个接口,让库用户实现,并确保在某些函数中,输入参数是给定接口的实现。怎么做 例如: /** * @interface */ var FooInterface = function(){}; /** * nothing special */ FooInterface.prototype.bar = function(){}; /** * @constructor * @implements {FooInterface} */ var Foo = function() {

我想定义一个接口,让库用户实现,并确保在某些函数中,输入参数是给定接口的实现。怎么做

例如:

/**
 * @interface
 */
var FooInterface = function(){};

/**
 * nothing special
 */
FooInterface.prototype.bar = function(){};

/**
 * @constructor
 * @implements {FooInterface}
 */
var Foo = function() { /* hello world */ };

/**
 * @override
 */
Foo.prototype.bar = function() { /* do something */ };


/**
 * ?? How to annotate, that 'foo' is an implementation of FooInterface,
 * but also instance of something else ??
 * @function
 * @param {FooInterface} foo
 */
 var the_function = function(foo) {
     // foo should be actually instance of Foo, but I want to make sure, 
     // it is an implementation of FooInterface
     // how to indicate that?
     foo.bar(); // code continues
 }

编辑:提问者在另一个论坛扩展了他的问题,该论坛的讨论线索提供了更多的见解


为了确保您的库函数
,_函数
实现接口,但不希望包含可能实现接口的定义(将
Foo
完全交给用户),您只需将参数收紧为不可为空的接口类型:

// ...snip: FooInterface declaration...
/**
 * @param {!FooInterface} foo
 */
var the_function = function(foo) {
  // non-nullable ensures that something like null.bar() is not invoked here.
  foo.bar(); 
};
用户必须定义自己的
FooInterface
实现,并将其作为
foo
参数传递。如果他要通过
FooInterface
,编译器将通过高级优化运行,检测到它不是构造函数(因为接口和构造函数是互斥的),并输出警告:

JSC_TYPE_MISMATCH: actual parameter 1 of the_function does not match formal parameter
found   : function (this:FooInterface): ?
required: FooInterface at line ... character ...
因此,通过收紧接口参数类型,您的需求得到了满足:“参数既是接口的实现,也是其他对象的实例”


另一种方法是提供一种功能最低的实现,既可以在库代码中执行
函数
,又可以作为用户实现的蓝图。您可以通过在库代码中包含
Foo
来实现这一点,并使
函数的定义依赖于
Foo

// ...snip: FooInterface declaration...
/**
 * @constructor
 * @implements {FooInterface}
 */
var Foo = function() {/* ... */};

/** @override */
Foo.prototype.bar = function() {/* ... */};

/** @param {!Foo} foo */
var the_function = function(foo) {
  foo.bar();
};
在这种情况下,
不需要使用任何引用
FooInterface
的内容对_函数进行注释。编译器将要求完成上述接口检查。如果
Foo
未能实现
bar()
,它将输出警告:
JSC\u接口\u方法\u未实现:接口Foo接口上的属性栏未通过第行的Foo类型实现。。。字符…


总之,这两种方法都满足了您的需求,但对您的库的用户来说意味着不同的东西:

  • 对于第一种方法,用户需要提供一个全新的类型,并用
    @implements
    注释
  • 使用第二种方法,您的用户可能必须使用自己的实现对
    Foo
    进行子类化。可能不需要引用接口。
    Foo
    中列出的基本功能可以重用

  • 如果您可以使用接口类型
    foointerace
    作为注释类型(如您的示例中),我不确定它是否有效,那么您可以使用
    instanceof
    在函数中测试对象的具体类型。见:

    如前所述,我不确定是否可以使用接口类型作为带注释的参数类型。否则,您可能必须使用未知类型注释(?)并对对象进行duck测试。只需确保在以任何方式访问字段之前将其强制转换为接口类型,这样编译器就可以在高级编译模式下正确解析属性名

    我会按照以下思路做一些事情:

    /**
      * @function
      * @param {*} foo
      */
    var the_function = function(foo) {
        // foo can be any object, we just want to make sure, 
        // it is implementing of FooInterface
        if (foo instanceof FooInterface) {
            (/** @type{FooInterface}*/(foo)).bar();
        } 
     };
    

    FooInterface的
    foo实例总是错误的,因为
    FooInterface
    从不在
    foo
    的继承链中。接口是闭包中的编译时构造,最终被剥离,因此不适合运行时检查。