皆様お久しぶりです
そろそろ、日記を書かないと「はてな市民権」を剥奪されそうなので、書いておきまつ><
最近
finally がマイブームです
どういうときに?
比較的に大規模な開発のとき(プロトタイプとかちゃんと使ってるとき)
どんなコードで?
こんなコード。 Fuga を継承した Hoge を作る場合とか
var Hoge = function() { /* ...(snip)... */ }; Hoge.prototype = new Fuga(); // メソッドのオーバーライド Hoge.prototype.getValue = function() { return Fuga.prototype.getValue.apply(this, arguments); };
この return 〜 .apply(this, arguments) までは定型区みたいなもんなので、まず書いちゃいますね。
で、たとえば、
getValue に事前処理を入れたければ
var Hoge = function() { /* ...(snip)... */ }; Hoge.prototype = new Fuga(); // メソッドのオーバーライド Hoge.prototype.getValue = function() { // 事前処理 this.value = 'hoge'; return Fuga.prototype.getValue.apply(this, arguments); };
こんな感じで書きます。
事後処理を入れたければ
var Hoge = function() { /* ...(snip)... */ }; Hoge.prototype = new Fuga(); // メソッドのオーバーライド Hoge.prototype.getValue = function() { // 事前処理 this.value = 'hoge'; var r = Fuga.prototype.getValue.apply(this, arguments); // 事後処理 delete this.value; return r; };
こんな感じですね。
でも、これだと
エラーが throw されたとき、事後処理が飛ばされるという危険性があったりしますね。
それに「var r」がめんどくさい感じです。
なので
最近はこんな感じで書くことが多いです。
var Hoge = function() { /* ...(snip)... */ }; Hoge.prototype = new Fuga(); // メソッドのオーバーライド Hoge.prototype.getValue = function() { // 事前処理 this.value = 'hoge'; try { return Fuga.prototype.getValue.apply(this, arguments); } finally { // 事後処理 delete this.value; } };
なんか、スッキリしませんか。
ただ、この方法だと返り値を使った処理が出来ないので、そういう場合は「var r」がいりますね。
ちょっと応用
最後に、この方法を使う典型的な例をあげておきます。
一時的に関数の意味を変える
継承元を書き換えずに、一時的に関数の意味を変える
var Hoge = function() { /* ...(snip)... */ }; Hoge.prototype = new Fuga(); // メソッドのオーバーライド Hoge.prototype.getValue = function() { this.getName = function() { return 'hoge' }; // 関数を一時的にオーバーライド try { return Fuga.prototype.getValue.apply(this, arguments); // この中では、オーバーライドされた関数を使う } finally { delete this.getName; // 関数を元に戻す。 delete しても、プロトタイプには残ってるので問題ない。 } };
メソッドの影響を調べる
これは、複雑なライブラリを使うときによく使います。
var Hoge = function() { /* ...(snip)... */ }; Hoge.prototype = new Fuga(); // メソッドのオーバーライド Hoge.prototype.getValue = function() { try { return Fuga.prototype.getValue.apply(this, arguments); } finally { console.log(this); // getValue が this に与える影響を調べる } };
ところで
「返り値」って変換したら、「返り血」になった。そんな金曜日。