DTPab

印刷やデザイン、アドビ製アプリやスクリプトなど、雑多な技術ブログ

よく使う処理・使うたび調べる処理はプロトタイプ拡張するといい

よく使う処理、いやむしろたまにしか使わなくて詳細を調べながら使う処理、ありますよね。
あと使うためにわざわざ値を変数に入れなくちゃいけない処理とか。
そういうものをプロトタイプ拡張して使いやすくできるのもJavaScriptのいいところです。

以下はそのサンプルですが、べき乗、四捨五入、小数点以下の桁数を指定して四捨五入の3例です。

Number.prototype.power = function (num) {
    return Math.pow(this, num);
};
Number.prototype.round = function () {
    return Math.round(this);
};
Number.prototype.roundSpecificDigit = function (num) {
    return Math.round(this * Math.pow(10, num)) / Math.pow(10, num);
};

これをこんなふうに使います。

var hoge = 3.141592;
$.writeln(hoge.power(3));
$.writeln(hoge.round());
$.writeln(hoge.roundSpecificDigit(2));
$.writeln(hoge.roundSpecificDigit(4));

結果はこちら。

f:id:uske_S:20190614163150p:plain

わざわざMathオブジェクトを介さなくて良いので、変数定義してMathオブジェクトのメソッドに入れて、新しい変数同士で計算して…という手間がなくなります。

ただもっと細かいこと言うと、引数が空の場合や文字列が渡された場合はどうするか*1とか、既にプロトタイプ拡張されていて同じメソッド名を上書きしてしまうことがないか*2とか、列挙可能プロパティ*3として定義してしまって良いかなど*4、考えるところはほかにあります。
とはいえ、DTPのスクリプトレベルではそこまで気にする必要もないので、ひとまず思ったようにプロトタイプ拡張して遊んでみるといいのかなと思います。

*1:引数のConstructor.nameを取得したり、typeof演算子で比較したりして、想定される引数の型以外であればTypeErrorを出力するようにすることが一般的です。今回は割愛します。

*2:if (!myClass.prototype.hoge) {...} といった定義のしかたをしますが今回は割愛します。

*3:列挙可能(enumerable)についてはこちらなど参照。
プロパティの列挙可能性と所有権 - JavaScript | MDN

*4:ES5からObject.definePropertyメソッドというものが追加されていて、上書き可能かなどまで含めてプロパティに定義できるようになりました。詳細はこちら。
Object.defineProperty() - JavaScript | MDN