2010/02/14
closure libraryでのクラス定義
ライブラリのコードではこんな書き方をしています。
Ariel = function() {ライブラリを使用しているところが一つもありませんね。
this.name = 'ariel';
};
Ariel.prototype.toString = function() {
return this.name;
};
Ariel.prototype.popup = function() {
alert(this.toString());
};
継承するにはgoog.inheritsを使います。
ArielNT = function() {
ArielNT.superClass_.constructor.call(this);
};
goog.inherits(ArielNT, Ariel);
ArielNT.prototype.toString = function() {
return ArielNT.superClass_.toString.apply(this, arguments) + '-networks';
};
prototype.jsのClass.createや$superに比べると随分と冗長です。
ただし$superの場合FunctionをtoStringして解析したりしているので、速度的にはclosure libraryの方が有利なのかもしれません。
最新版のclosure libraryにはgoog.baseと言うメソッドが追加されています。
これを使うとさっきのArielNTクラスは以下のように書けます。
ArielNT = function() {
goog.base(this);
};
goog.inherits(ArielNT, Ariel);
ArielNT.prototype.toString = function() {
return goog.base(this, 'toString') + '-networks';
};
そしてArielNTクラスを定義したファイル(ariel-nt.js)を作成して、これをclosure compilerに渡してみましょう。
$ java -jar compiler.jar -js ariel-nt.js -js_output_file ariel-nt-compiled.js読みやすいようにインデントします。
ArielNT = function(){goog.baseを展開してくれています。
Ariel.call(this)
};
goog.inherits(ArielNT, Ariel);
ArielNT.prototype.toString = function(){
return ArielNT.superClass_.toString.call(this) + "-networks"
};
ちなみにgoog.baseを展開してくれるのは上記のようにArielNT.prototypeに一つずつメソッドやフィールドを追加した場合だけです。
例えばprototype.jsみたいに
goog.mixin(ArielNT.prototype, {と書くとコンパイル時にエラーになります。(goog.mixinはprototype.jsのObject.extend)
toString: function() {
return goog.base(this, 'toString') + '-networks';
}
});
ariel-nt.js:8: ERROR - incorrect use of goog.base: Could not find enclosing method.
return goog.base(this, 'toString') + '-networks';
^
1 error(s), 0 warning(s)
- Category(s)
- JavaScript
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/uchida/closure-library306e30af30e930b95b9a7fa9/tbping