Closure Compiler と JsDoc3 @lendsの書き方
@lendsの書き方についての覚書
いちいちClass.prototype.method = function(){};
といった書き方をするのは面倒なので、
なんらかの関数でオブジェクトを受け取ってprototypeに関数を定義することが多いと思う。
たとえば以下の様なコード
function defineMethods(clazz, instance_methods) {
if (instance_methods) {
for (var k in instance_methods) {
if (instance_methods.hasOwnProperty(k))
clazz.prototype[k] = instance_methods[k];
}
}
};
/** @interface */
function Interface(){};
/** @expose */
Interface.prototype.say = function() {};
/** @constructor
* @implements {Interface} */
function ConcreteClass() {
};
defineMethods(ConcreteClass, /** @lends {ConcreteClass.prototype} */ {
say: function() { console.log('hoge'); }
});
window['ConcreteClass'] = ConcreteClass;
これでClosureは正常にコードを出力してくれるのだが、JsDoc3ではsayがConcreteClassのmethodsの一覧にのってこない。
@lendsの書式は以下のページにある通りで、Closure側にあわせた形。
https://developers.google.com/closure/compiler/docs/js-for-compiler
一方、JsDoc3では@lendsは以下
http://usejsdoc.org/tags-lends.html
@lends は {} で囲わずに普通に名前を書くとなっている。
もともと、{}は 型 を示すときに使う記号なので、JsDoc側の記述の方が自然に思うので そちらにあわせてみる。
function defineMethods(clazz, instance_methods) {
if (instance_methods) {
for (var k in instance_methods) {
if (instance_methods.hasOwnProperty(k))
clazz.prototype[k] = instance_methods[k];
}
}
};
/** @interface */
function Interface(){};
/** @expose */
Interface.prototype.say = function() {};
/** @constructor
* @implements {Interface} */
function ConcreteClass() {
};
defineMethods(ConcreteClass, /** @lends ConcreteClass.prototype */ {
say: function() { console.log('hoge'); }
});
window['ConcreteClass'] = ConcreteClass;
これを ADVANCED OPTIMIZATIONSでコンパイルすると以下の通りできちんと認識できているみたい。
X:\>jscomp --warning_level VERBOSE --compilation_level ADVANCED_OPTIMIZATIONS a.js
function a(){}var b={<strong>say</strong>:function(){console.log("hoge")}},c;for(c in b)b.hasOwnP
roperty(c)&&(a.prototype[c]=b[c]);window.ConcreteClass=a;
ということで、@lends xxxと書く事にして、@lends {xxx}は使わない事にする。