関数の可変長な仮引数を直接コンストラクタに渡す

ある関数が受け取る可変長引数を、コンストラクタに直接渡す方法

要するにコンストラクタが可変長引数を受け取るのでファクトリ関数も可変長引数を使えるようにしたいんですよ。

ES2015ならばこう。

'use strict';
class Hoge {
  constructor(...args) {
    console.log(`引数は${args.length}個`);
  }
}

function createHoge(...args) {
  return new Hoge(...args);
}

createHoge(1);
createHoge(1, 2)
createHoge(1, 2, 3);

で、本題は次、スプレッド演算子とレストパラメータが使えない場合。LTSのnode.js v4系等ではどうするか?

普通の関数ならapplyでいい。

'use strict';
function hoge(var_args) {
  console.log(`引数は${arguments.length}個`);
}

function execHoge(var_args) {
  var args = Array.from(arguments);
  hoge.apply(null, args);
}

execHoge(1);
execHoge(1, 2)
execHoge(1, 2, 3);

しかし相手がコンストラクタの場合、new Hoge.apply(null, args) とするとapplyはコンストラクタじゃねーぞと言われてしまう。

ここは bind を使って頑張れば実現できそうな感じです。

'use strict';
class Hoge {
  constructor(var_args) {
    console.log(`引数は${arguments.length}個`);
  }
}

function createHoge(var_args) {
  var args = Array.from(arguments);
  args.unshift(null);
  return new (Function.prototype.bind.apply(Hoge, args))();
}

createHoge(1);
createHoge(1, 2)
createHoge(1, 2, 3);

bind.apply(Hoge, args)とするのがポイント、bindに対してapplyを実行することで引数を束縛したHogeコンストラクタを生成できるのだ。

非常にわかりにくいですねー。以上、今後全く役立たない技でしたー。