😽

一日一処: 「時は金なり」を再現するJavaScriptテクニック

2024/02/24に公開

時は金なり

時は、金だということ。とても大切なこと。これを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