2012-06-24 92 views
2

我正在使用使用return語句來公開類方法的設計模式。Google Closure編譯器,如何優雅地處理JSC_INEXISTENT_PROPERTY?

問題是:我得到一個很多JSC_INEXISTENT_PROPERTY警告在關閉編譯器的高級模式,這使得它很難檢查實際問題的警告。該圖案的

實施例I使用:

// ==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'); 

輸出(格式化):

(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; 

就解決了問題,但我不知道這是否是最好的解決方案。我不知道編譯器是如何工作的,但我可以想象如果你有一個構造函數,它期望實例屬性被分配到構造函數內的thisMyClass.prototype

如果刪除@constructor註釋並忽略new,那麼就沒有警告(但編譯後的代碼僅是console.log("Hello World");

3

您還可以使用:

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

該功能可與「新」的叫,但不會返回「MyClass的」的一個實例。

+0

當我測試它時,將新註釋與記錄類型一起使用會生成「錯誤類型註釋」錯誤。 –

+0

這是不幸的,我們應該修復它。 – John

+1

它使用typedef。 –

相關問題