2012-06-24 3 views
2

Я использую шаблон дизайна, который использует оператор return для раскрытия методов открытого класса.Компилятор Google Closure, как правильно обрабатывать JSC_INEXISTENT_PROPERTY?

Проблема: Я получаю много из JSC_INEXISTENT_PROPERTY предупреждений в расширенном режиме Closure Compiler, который делает его трудно проверить предупреждения, которые на самом деле имеют значение.

Пример шаблона я использую:

// ==ClosureCompiler== 
// @compilation_level ADVANCED_OPTIMIZATIONS 
// ==/ClosureCompiler== 

/** 
* @constructor 
*/ 
var MyClass = function() { 

    var someFunc = function(myString) { 
     console.log(myString); 
    } 

    return { 
     myPublicFunc: someFunc 
    }; 
} 

var myClassInstance = new MyClass(); 
myClassInstance.myPublicFunc('Hello World'); 

предупреждение:

JSC_INEXISTENT_PROPERTY: Property myPublicFunc never defined on MyClass \ 
    at line 16 character 0 
myClassInstance.myPublicFunc('Hello World'); 

Output (отформатированный):

(new function() { 
    return { 
     a: function(a) { 
      console.log(a) 
     } 
    } 
}).a("Hello World"); 

Что странно, потому что закрытие поняло, что код был правильное выполнение и компиляция кода, переименование myPublicFunc последовательно a. Так почему я получил это предупреждение? Я делаю что-то неправильно?

Примечание. Я не хочу отключать эти предупреждения, потому что это также скроет предупреждения, о которых я действительно беспокоюсь. Я также не хочу использовать цитированные строки или экспорт, потому что я хочу, чтобы Closure сжимал их.

ответ

4

Ваша функция помечается неправильно. Это на самом деле не является конструктором и в этом случае new ключевых слов .. не нужна Ваша функция просто возвращает анонимный тип с myPublicFunc собственности

Для аннотировать такой шаблон, вы должны использовать тип записи:

/** @return {{myPublicFunc: function(string) }} */ 
var MyClass = function() { 

    var someFunc = function(myString) { 
     console.log(myString); 
    } 

    return { 
     myPublicFunc: someFunc 
    }; 
}; 

var myClassInstance = MyClass(); // new keyword not needed 
myClassInstance.myPublicFunc('Hello World'); 

Другой вариант аннотации - это создать интерфейс и ввести тип возвращаемого объекта в качестве интерфейса. Эта опция была бы полезна, когда несколько функций возвращают объект, соответствующий одному и тому же интерфейсу.

1

Добавление

MyClass.prototype.myPublicFunc = null; 

бы решить эту проблему, хотя я не знаю, является ли лучшим решением.

Я действительно не знаю, как работает компилятор, но я мог предположить, что если у вас есть функция-конструктор, ожидается, что свойства экземпляра будут назначены this внутри конструктора или MyClass.prototype.

Если удалить @constructor аннотацию и опустить new, то не предупреждение (но скомпилированный код только console.log("Hello World");.

3

Вы также можете использовать:

/** @type {function(new:{myPublicFunc: function(string)})} */ 
var MyClass = function() {... 

Функция может быть вызвана с «новым», но не возвращает экземпляр «MyClass».

+0

Использование новой аннотации с типом записи генерирует ошибку «аннотации« плохого типа »при ее тестировании. –

+0

Это несчастливо, мы должны это исправить. – John

+1

Работает с typedef. –

Смежные вопросы