😽
一日一処: 「時は金なり」を再現するJavaScriptテクニック
時は金なり
時は、金だということ。とても大切なこと。これをJavaScriptで表現する。
Time is Money
英語だと、Time is moneyだ。これをそのまま表現できると一番いいのだが、JavaScriptの場合は、簡単にはできない。そのため、文字列に対して、メソッドを設定することで、これを再現できる。
Stringのprototype
prototypeにメソッドを追加すれば、実行しているプログラム全体で、恩恵を受けることができる。ただし、標準の仕組みに対して、このようなことをするのは、実行環境を汚染するため、本来は適切ではない。単純なテクニックとして認識して、実務では使わないように注意が必要である。
String.prototype.is = function(value) {
return this.valueOf() === 'time' && value === 'money'
}
文字列にisメソッドを追加する。このメソッドでは、文字列自身の値がtimeであること、そして、引数に渡される値がmoneyである場合に、真を返すメソッドだ。後はこれを使うことで、time is moneyが実現できる。
const time = 'time';
if (time.is('money')) {
console.log('Exactly! Time is money');
}
簡単だ。他の文字列を使用した場合は、偽となるため、何も出力されない。このように、JavaScriptでは、既存のクラス(String)にメソッドを追加することができる。だが、あまり行うべきではない手法だ。
クラスを用いて
普通に考えると、金も時も単なる文字列であることは、些か気になる点だ。そのため、それぞれをクラスとして定義した上で、同じ様に比較を行うようにしよう。
class Material {
is(value) {
const selfIsTime = this.constructor === Time
const valueIsMoney = value.constructor === Money
return selfIsTime && valueIsMoney
}
}
class Time extends Material {}
class Money extends Material {}
time = new Time()
money = new Money()
if (time.is(money)) {
console.log('Exactly! Time is money');
}
特におもしろいことは何もしていないが、TimeもMoneyもそれぞれ同じクラスを継承している。ただこれは、以下のようにしても真にはならない。
if (money.is(time)) {
console.log('not output'); // 出力されない
}
個人的に、金は時なりとは聞いたことがないためであるが、お互いを比較させようとしている仕組みであるため、両方ともに同じ機能をもたせたく、同じクラスを継承している。
Discussion