🌊

一日一処: JavaScriptの汚染も厭わぬ機能の拡張

2024/01/28に公開

機能の拡張

元来、プログラミング言語には、事前に複数の機能が備わっている。特に、ファイル処理や文字列、数値に対する処理は、ほとんどの言語に実装されているだろう。
その中で、本来存在しないが用いたい機能については、ライブラリ等を利用して、様々な機能を実装してきた。
現在は、よく使用されるプログラミング言語には、パッケージ管理を行う仕組みが既存で備わっていたり、後天的に導入することも可能だ。ただ、このような便利な仕組みが登場する前は、自ら機能するプログラムファイルを導入していた。

汚染を伴う機能拡張

その中で、最近はあまり見ることもなく、そして、ご法度と考えられる機能の拡張方法が存在する。
例えば、配列の中身をすべて表示するための仕組みを考えよう。

const names = ['Bob', 'Alice']
names.forEach((n) => console.log(n))
// Bob
// Alice

非常に簡単な例ではあるが、この処理が複雑となり、複数の箇所で用いなければならない場合、forEachに渡しているコールバック関数は、別の箇所で定義し、使用するたびにそれを呼び出すことになるだろう。

const names = ['Bob', 'Alice']
const jobs = ['Doctor', 'Teacher']
const callback = (n) => console.log(n)
names.forEach(callback)
jobs.forEach(callback)
// Bob
// Alice
// Doctor
// Teacher

ただし、コールバック関数を設定しなければならないことを考える人によっては少々面倒かもしれない。
掲題にもあるとおり、JavaScriptの標準的な機能を汚染することで、このようなことも可能だ。

const names = ['Bob', 'Alice']
const jobs = ['Doctor', 'Teacher']
Array.prototype.outputAll = function() {
  this.map((n) => console.log(n))
}
names.outputAll()
jobs.outputAll()
// Bob
// Alice
// Doctor
// Teacher

スッキリしたのではないだろうか。prototypeは、インスタンスから参照されるクラス(オブジェクト)そのものにメソッドなどを追加できる仕組みだ。これは、非常に面白い振る舞いをするので、関心を持った方はぜひしっかりと学んでほしい。
ただし、このように、既存の仕組みに対して、新たな機能を追加するということは、既存の機能に対して、汚染していることを忘れてはならない。

Discussion