web-dev-qa-db-ja.com

ES6でクラスのインスタンスを動的な名前で作成しますか?

文字列変数を関数に渡すことで、特定のES6クラスをインスタンス化できるようにしたいと思います。変数の値に応じて、異なるクラスが作成されます。

-私は2つのクラス、ClassOneClassTwoを持っています。変数を関数に渡し、新しいクラスを取得できるようにしたいのです。クラスの名前は変数に関連付けられます-例えば。 'Two'ClassTwoを作成します。

I しないこのようなswitch句を使用したいだけです:

function createRelevantClass( desiredSubclassName )
{
  let args = [],
      newClass;

  switch( desiredSubclassName )
  {
    case 'One' :
      newClass = new ClassOne(args);
      break;
    case 'Two' :
      newClass = new ClassTwo(args);
      break;
  }

  return newClass;
}

代わりに、変数名を使用してコンストラクター呼び出しを何らかの方法で作成できるようにします。それは可能ですか?

function createRelevantClass( desiredSubclassName )
{
  // desiredSubclassName would be string 'One' or 'Two'

  // how to use the 'new' operator or Reflect here to create the class based on the variable passed in
  let newClass = ( *magic code to build constructor dynamically* );

  return newClass;
}
35
raffjones

これを達成する方法はいくつかあります...

1.プロキシクラス

名前からクラスへのマッピングを維持する@thefourtheyeの例に従って、目的のクラスの名前を取得し、そのインスタンス化をプロキシすることを仕事とするクラスを作成できます。

[ 動作を確認 ]

クラスを定義する

// ClassOne.js
export class ClassOne {
    constructor () {
        console.log("Hi from ClassOne");
    }
}

// ClassTwo.js
export class ClassTwo {
    constructor (msg) {
        console.log(`${msg} from ClassTwo`);
    }
}

プロキシクラスを定義する(例:DynamicClass

import ClassOne from './ClassOne';
import ClassTwo from './ClassTwo';

// Use ES6 Object Literal Property Value Shorthand to maintain a map
// where the keys share the same names as the classes themselves
const classes = {
    ClassOne,
    ClassTwo
};

class DynamicClass {
    constructor (className, opts) {
        return new classes[className](opts);
    }
}

export default DynamicClass;

使用例

import DynamicClass from './DynamicClass';

new DynamicClass('ClassOne'); //=> "Hi from ClassOne"
new DynamicClass('ClassTwo', 'Bye'); //=> "Bye from ClassTwo"

2.工場機能

クラス名->クラスマッピングのオブジェクトに対してルックアップを実行し、クラスへの参照を返す関数を使用します。その後、通常どおりインスタンス化できます。

ファクトリー関数を定義する

import ClassOne from './ClassOne';
import ClassTwo from './ClassTwo';

const classes = { ClassOne, ClassTwo };

export default function dynamicClass (name) {
  return classes[name];
}

使用例

import dynamicClass from './dynamicClass'

const ClassOne = dynamicClass('ClassOne') // Get the ClassOne class

new ClassOne(args) // Create an instance of ClassOne
46
sdgluck

クラスにオブジェクトを格納します。キーは、必要なクラスの名前です。

const classesMapping = {
  'One': ClassOne,
  'Two': ClassTwo
};

次に、このようなキー名に基づいてクラスを作成します

return new classesMapping[desiredSubclassName](args);
20
thefourtheye