Анонимный экземпляр класса ---- это плохая идея?

В ES6 мы можем сделать анонимный класс:

var entity = class {
}

Но мы также можем его создать:

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

Что делается за ним, какая польза от него принесет и какие оговорки он принесет?

Ответы

Ответ 1

Анонимный экземпляр класса - это плохая идея?

Да, очень плохой. Просто не так плохо, как new function() { … } был в ES5.

Этот стиль записи приводит к созданию новой функции-конструктора и объекта-прототипа каждый раз, когда выражение оценивается. Если вы создаете несколько объектов с таким подходом, они не получат ни одного из преимуществ классов/прототипов.

Если вы создали этот шаблон для создания одноэлементного объекта, вам тоже не удалось. Конструктор все еще создан, и он даже доступен - второй экземпляр можно легко создать с помощью new entity.constructor, победив всю цель.

Значит не использовать его. Простой объектный литерал гораздо проще писать, читать и создавать экземпляры:

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

Не обманывайте себя другими языками, где шаблон new class является общим, он работает очень по-другому, чем в JavaScript.

Ответ 2

Возможно, вам понадобятся анонимные классы, если вы точно знаете, что делаете, вы создаете иерархию классов (то есть вещей, которые вы хотите копировать) в хорошо продуманной системе метапрограммирования, и нет другого элегантного решения для расширения, например

{
    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+... вам нужны конструкторы, супер, расширяемые, статические методы и т.д.... или нет? Вы застряли в работе с классами, которые уже существуют, или вы можете написать все, используя объекты и утверждения? И действительно ли это так? Нужно быть анонимным? Эти вопросы могут помочь вам решить.).