Мгновенный запуск javascript-класса без вызова конструктора

ReactiveRaven спросил: 12 мая 2018 в 03:41 в: javascript

Краткая версия

Учитывая следующий класс:

class Foo {
    constructor() {
        throw new Error("No!")
    }    // ... more functions ...
}

Как я могу получить экземпляр Foo?

Объяснение

Класс на самом деле выглядит следующим образом:

const KEY = Symbol("BAR")
function validateBarData(input) { 
    /* throws error if input is not in the format: */
    /* {name: "string", bartender: "string", drinks: [ "string" ]} */
}
class Bar {
    constructor(name, bartender, drinks) {
        this[KEY] = {name: name, bartender: bartender, drinks: drinks}
        // now validate to protect against garbage input like
        //   'name = 42' or 'drinks = undefined', etc.
        validateBarData(this[KEY])
    }    encode() {
        return this[KEY]
    }    static decode(data) {
        validateBarData(data)
        return new Bar(data.name, data.bartender, data.drinks)
    }    // ... more functions ...
}

encode() и Bar.decode(data) используются для сериализации состояния для чего-то JSON.stringify, что позволяет воссоздать объект позже. Фактическая логика кодирования / декодирования здесь может быть более сложной, чем просто "dump this[KEY]" (например, объекты кодирования, управляемые объектом Bar).

Проблемы при декодировании :

  • validateBarData вызывается дважды
  • Хотя у нас уже есть допустимое внутреннее состояние для назначения this[KEY] после первой строки decode, он сначала должен быть разрушен, а затем воссоздан.

Я бы хотел избежать этого дублирования, но я не смог найти правильный путь чтобы сделать это.

Как я могу это сделать?

1 ответ

ReactiveRaven ответил: 12 мая 2018 в 03:41

Упс.

let foo = Object.create(Foo.prototype)

или

static decode(data) {
    validateBarData(data)
    let bar = Object.create(Bar.prototype)
    bar[KEY] = data
    return bar
}

Секунды перед отправкой вопроса я пробовал последнее, и получается, что я должен был вызывать Object.create прототип, а не сам класс. Как смущающе ...

Я все равно публикую, потому что ключевые слова в заголовке вопроса не отображаются в результатах поиска (на момент написания, много о java, но не javascript), так что, возможно, это "Я оставлю время в будущем".