web-dev-qa-db-ja.com

匿名クラスインスタンス----それは悪い考えですか?

ES6では、匿名クラスを実行できます。

var entity = class {
}

ただし、インスタンス化することもできます。

var entity = new class {
    constructor(name) { this.name = name; }
    getName() { return this.name; }
}('Foo');
console.log(entity.getName()); // Foo

その背後で何が行われ、どのような利点がもたらされ、どのような警告ももたらされますか?

23
Steve Fan

匿名クラスインスタンス—それは悪い考えですか?

はい、非常に悪いものです。ちょうど new function() { … }がES5にあったのと同じくらい悪い

この記述スタイルにより、式が評価されるたびに新しいコンストラクター関数とプロトタイプオブジェクトが作成されます。このアプローチで複数のオブジェクトを作成すると、クラス/プロトタイプの利点はまったく得られません。

このパターンがシングルトンオブジェクトを作成することを意図していた場合、同様に失敗しました。コンストラクターはまだ作成されており、アクセス可能です-new entity.constructorを使用して2番目のインスタンスを簡単に作成でき、目的全体を無効にします。

したがって、決して使用しないでください。単純なオブジェクトリテラルは、書き込み、読み取り、およびインスタンス化がはるかに簡単です。

var entity = {
    name: 'Foo',
    getName() { return this.name; }
};
console.log(entity.name); // Foo

new classパターンが一般的である他の言語にだまされないでください。JavaScriptの場合とは動作が大きく異なります。

37
Bergi

自分が何をしているかを正確に知っていて、よく考え抜かれたメタプログラミングシステムでクラスの階層(つまり、コピーが必要なもの)を作成している場合、匿名クラスが必要になることがあります。例えば.

{
    myImplementation: class extends MyBaseClass {
        someMethod(x) {
            super().someMethod(x);
            insert extended behavior
        }
    }
}

もちろん、Object.assignを使用する不正なマジック関数を使用して上記を実装できます。

{
    myImplementation: extendMagic(mySuper => ({
        someMethod(x) {
            mySuper.someMethod(x);
            insert extended behavior
        }
    }))
}

またはあなたがやっていることを行うためのいくつかのより良い方法を見つけます。しかし、不自然なユースケースが時折(まれに)存在します。

ユースケースは決して素晴らしいものではありませんが、プロトタイプの継承では書きにくいクラス機能が必要なときに最も魅力的です(そしてもちろんクラスはプロトタイプの継承の一種のラッパーなので、ユースケースは構文的なシュガープラスが必要になりますes6 +クラス機能...コンストラクター、スーパー、エクステンド、静的メソッドなどが必要ですか?すでに存在するクラスで作業をしているのですか、オブジェクトとアサートを使用してすべてを書くことができますか?そして本当に必要なのですか? be anonymous?これらの質問はあなたの決定に役立つかもしれません。).

3
ninjagecko