Javascript 在函数中包装代码时如何定义全局类型

Javascript 在函数中包装代码时如何定义全局类型,javascript,google-closure-compiler,google-closure,Javascript,Google Closure Compiler,Google Closure,这个问题是关于正确使用Google闭包编译器的类型注释 我们有一个约定,每个javascript文件都封装在一个函数中。示例文件: Square.js: (function() { 'use strict'; /** * @constructor */ function Square() {}; Square.prototype.draw = function() { }; }()); (function() { 'us

这个问题是关于正确使用Google闭包编译器的类型注释

我们有一个约定,每个javascript文件都封装在一个函数中。示例文件:

Square.js

(function() {
    'use strict';

    /**
     * @constructor
     */
    function Square() {};

    Square.prototype.draw = function() {
    };

}());
(function() {
    'use strict';

    /** @param {Square} square */
    function drawSquare(square) {
        square.draw();
    }

}());
如果我们在这个函数中定义了一个类型(比如构造函数),闭包编译器在其他文件中就不会知道它。例如,在另一个文件中:

foo.js

(function() {
    'use strict';

    /**
     * @constructor
     */
    function Square() {};

    Square.prototype.draw = function() {
    };

}());
(function() {
    'use strict';

    /** @param {Square} square */
    function drawSquare(square) {
        square.draw();
    }

}());
使用
-W VERBOSE
编译时会出现一个错误,即未定义类型
Square

foo.js:4: WARNING - Bad type annotation. Unknown type Square
        /** @type {Square} square */
                   ^

0 error(s), 1 warning(s), 83.3% typed
为了解决这个问题,我们在单独的文件中为所有类创建了外部。创建externs是一个糟糕的解决方案,因为现在我们必须为每个类维护两个文件

  • 如果文件由文件级函数包装,是否可以共享这些类型
  • 在文件之间共享类型时,通常推荐使用闭包的方法是什么?使用闭包库是否以任何方式提供/需要帮助

  • 我想您可以通过在封闭函数的限制范围之外导出具有您想要使用的名称的符号来实现它。大概是这样的:

    (function() {
        goog.provide('Square');
        //'use strict';
    
        /**
         * @constructor
         */
        function Square() {};
    
        Square.prototype.draw = function() {
          return "\\o/";
        };
        goog.exportSymbol('Square', Square);
    }());
    
    然而,我认为你的问题在于:

    我们有一个约定,每个javascript文件都封装在一个函数中

    闭包有一个不同的约定,即

    要回答您的第二个问题,建议的结束方式是:

    goog.provide('my.Square');
    /**
     * @constructor
     */
    my.Square = function() {
    };
    
    my.Square.prototype.draw = function() {
      // TODO
    };
    
    以及:


    @Epasarello,这是如何回答这个问题的?你没有看到标题“当我在类型检查的情况下编译时,我收到了关于“坏类型注释”的警告吗。未知类型“来自闭包库文件”。我建议您阅读感谢-我将更详细地了解使用goog.provide/require和使用名称空间。我对这本书唯一关心的是,它现在已经有4年的历史了。另外-文件级函数包装的原因是能够放置“严格模式”语句,而不会影响我们所依赖的任何非严格的第三方代码(并且不编译);并在开发中启用它(我们不使用闭包的输出)。因此,我不知道如何使用名称空间约定来记住这一点,因为这本书仍然非常有效。您可能还希望使用
    goog.scope
    来满足您的需求。