Menu

キーワード

  • JavaScript
  • prototype

したいこと

サーバーから受け取るリストはArrayとして扱える。そこに業務的な独自関数を追加して、ロジックの流出を防ぎたい。

たとえば、次のように相乗できる配列を作ることを考えてみる。

const org = { __content: [1, 2, 3] }; // または直接 [1, 2, 3]
const collection = raisableCollectionOf(org);
collection.raise().raise(); // [1, 16, 81]

どうやって

コレクションをフィールドにもつなら

const org = { __content: [1, 2, 3] };

とする場合。(フロント側ではあんまりやらないかも。)

ファーストクラスコレクションの形でデータをもつなら、その型のprototypeに関数をもたせることができる。

function FirstClassCollection() {
  this.__content;
}
FirstClassCollection.prototype.size = function () {
  return this.__content.length;
};
FirstClassCollection.prototype.map = function (...args) {
  const newCollection = Object.create(Object.getPrototypeOf(this));
  newCollection.__content = this.__content.map(...args);
  return newCollection;
};

function firstClassCollectionOf(target) {
  Object.setPrototypeOf(target, FirstClassCollection.prototype);
  return target;
}
function RaisableCollection() {
  this.__content;
}
Object.setPrototypeOf(RaisableCollection.prototype, FirstClassCollection.prototype);
RaisableCollection.prototype.raise = function() {
  return this.map(value => value * value)
};

function raisableCollectionOf(target) {
  Object.setPrototypeOf(target, RaisableCollection.prototype);
  return target;
}

コレクションをフィールドにもたなくてもいい

const org = [1, 2, 3];

とする場合。(こちらの方が普通かも。)

表示データとしてはわざわざコレクションをフィールドにもつファーストクラスコレクションの形にしないかもしれない。

JavaScriptではprototypeチェーンでArrayをラップして関数をもたせることができる。

function RaisableCollection() {
}
Object.setPrototypeOf(RaisableCollection.prototype, Array.prototype);
RaisableCollection.prototype.raise = function() {
  return raisableCollectionOf(
    this.map(value => value * value)
  );
};

function raisableCollectionOf(target) {
  Object.setPrototypeOf(target, RaisableCollection.prototype);
  return target;
}

なお書き

  • 新しいclassもprototypeのシンタックスシュガーなんだってね。

参考

スポンサーリンク