[英]How to get closure compiler to properly check the properties of a constructor in javascript
我不明白如何獲取適用於JavaScript的Google閉包編譯器以正確識別構造函數的屬性。 例如,在下面的代碼中,我不知道在第27行中賦予'cls'的類型是什么,以便編譯器不會產生以下(我認為是錯誤的)錯誤:
foo.js:29:警告-屬性聲明永遠不會在cls cls.say();上定義 ^
通過閱讀文檔,看來我應該像在25中那樣做。有人可以幫忙嗎? 謝謝,
1 /**
2 * @interface
3 **/
4 function Sayer() {}
5 Sayer.prototype.say = function() {};
6 Sayer.say = function() {};
7
8 /**
9 * @constructor
10 * @implements {Sayer}
11 **/
12 function A() {}
13 A.say = function() { console.log('A factory'); };
14 A.prototype.say = function() { console.log('Am an A'); }
15
16 /**
17 * @constructor
18 * @implements {Sayer}
19 **/
20 function B() {}
21 B.say = function() { console.log('B factory'); };
22 B.prototype.say = function() { console.log('Am an B'); };
23
24 /**
25 * @param {function(new:Sayer)} cls
26 **/
27 function makeSayer(cls) {
28 var obj = new cls();
29 cls.say();
30 obj.say();
31 }
32
33 makeSayer(A);
34 makeSayer(B);
接口上的“ Sayer.say”將被忽略。
您是否正在為Closure的高級模式做准備? 在高級模式下,“ A.say”和“ B.say”被重命名為“ A $ say”和“ B $ say”,類型檢查會期望這一點並適當地抱怨它(不會有方法A.say )。
您可以通過間接添加來避免崩潰:
function addSay(sayer, fn) {
sayer.say = fn;
}
我想您可以通過添加如下行來避免類型警告:
Function.prototype.say;
但是我不確定這就是您想要的。
您可以避免麻煩,並將其添加到原型中,然后調用它:
A.prototype.classSay = function () {};
問題是一個接口(上定義的方法之間的區別A.say
)對上的一個接口的原型(定義的方法A.prototype.say
)。 在Closure的類型系統中, @interface
標記提供以下保證:
任何實現接口的類都必須實現接口原型上定義的所有方法和屬性。
注意,它只關心原型上的方法。 它不在乎接口本身的方法。
假設您創建一個實現Sayer
的新類C
關閉將確保您定義C.prototype.say
。 但是,您可以跳過C.say
。 您不需要實施它。 以下是一個完全有效的Sayer
。
/**
* @constructor
* @implements {Sayer}
*/
function C() {}
C.prototype.say = function() { console.log('Am a C'); }
由於這是有效的Sayer
,因此應該安全地調用makeSayer(C)
。 現在很清楚,為什么您對makeSayer
的定義不正確。 它假定已定義cls.say
,但Closure不提供此類保證。 關閉可以發現問題,並為您提供適當的錯誤消息。
那你該怎么辦?
如果要遵循標准的面向對象方法,則可能需要兩個接口,一個用於工廠SayerFactory
,一個用於其創建的對象Say
。 您所有的方法都將成為原型中定義的方法,而Closure將為您進行所有檢查。
但是,如果您喜歡在構造函數中使用say
方法的想法,則可以嘗試使用鴨子類型來強制執行factory方法。 就像是:
/**
* @param {{say:function():Sayer}} cls
*/
function makeSayer(cls) {
...
}
當然,如果您需要定義不止一種方法,那么鴨子輸入法將無法很好地擴展。 對於每種定義的方法,類型簽名將變得越來越大。
祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.