В этом примере вы можете просто предоставить замыкание, которое полностью уменьшит эту необходимость.

const getLoggerWithMemoizedID = id => () => ({
  log: () => console.log(id)
});
const makeLoggerThatLogsJibberish =
  getLoggerWithMemoizedID(
    'aksljhflkajshdflkajshfkjhsfslkjhlkjshd'.repeat(9999));
const instances = Array.from({ length: 1000 },
  makeLoggerThatLogsJibberish);
// Memory Used: 119320

Взгляните на это, 9-кратное уменьшение размера, просто делая то, что вы делали в своем примере. С одним ключевым отличием.

В моем примере я знаю, что все регистраторы, привязанные к этому идентификатору, безопасны, поскольку я знаю, что ничто не может коснуться этого идентификатора. В вашем примере вы в основном делаете «ID» статическим значением каждого класса, который его использует, и каждого класса, который наследуется от класса, который его использует.

Не знаю, как вы, но когда я работаю над серверной частью, где у меня могут быть тысячи клиентов на этом экземпляре моего сервера, я действительно не хочу нести ответственность за случайное предоставление не тому пользователю доступа к неправильному «ID». ». GDPR, HIPPA и другие…

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

Но это кажется мне немного тяжеловатым.

На самом деле, если бы я занимался функциональным программированием, я бы смог уменьшить эту проблему, используя еще меньше памяти:

const id = 'aksljhflkajshdflkajshfkjhsfslkjhlkjshd'.repeat(9999);
const log = x => console.log(x);
const instances = Array.from({ length: 1000 }).fill(log);
// Memory Used: 13784

Вот в чем дело, если мы говорим о функциональном программировании, то мы говорим о разделении между данными и поведением. По крайней мере, с точки зрения собственности. Давайте, например, посмотрим на сумматор ООП:

// yes, I know this is a future spec; I am using it for brevity
class Adder {
  #a = 0;
  #b = 0;
  #sum = 0;
  setX (x) {
    #a = x;
  }
  setY (y) {
    #b = y;
  }
  add () {
    #sum = #a + #b;
  }
  getSum () {
    return #sum
  }
}

Навскидку, сколько здесь будет возникать условий гонки на основе параллелизма и случайных ошибок на основе состояния? Даже просто ошибки организации кода, которые принимают форму:

doX();
doY();
doZ(); // *KABOOM*
// ...hmmm
doX();
doZ();
doY(); // All better! Of course, it was so obvious the whole time!

А пока давайте посмотрим на версию add для FP:

const add = (x, y) => x + y;

Или, если вы хотите немного оживить ситуацию

const add = curry((x, y) => x + y);
// which is just (x) => (y) => x + y;
// pick your lib of choice for `curry` or roll your own in 6 lines

Обратите внимание, что сумматор FP отделил владение данными от поведения. Вместо того, чтобы создавать 1000 экземпляров объектов с методом добавления и внутренним состоянием (поскольку давайте посмотрим правде в глаза, если ваша система не *действительно* проста, числа, которые вы собираетесь сложить вместе, могут *не* поместиться в прототипе как статические значения) , мы отделили поведение от данных и теперь можем использовать одну и ту же функцию add для 1000 пар чисел.

Это было бы похоже на

class Adder {
  static add (x, y) { return x + y }
}

в случае, когда вы действительно хотите, чтобы существительное содержало глагол. Что совершенно нормально. Пространство имен — важная вещь. Это также форма, одобренная дядей Бобом, в том смысле, что она не изменяет состояния, ее легко обосновать и каждый раз возвращать предсказуемый результат.

Если ваш аргумент заключается в том, что вы должны использовать классы ES6, а не поддерживаемый Yahoo «шаблон раскрытия модулей», который был рекомендован Дугласом Крокфордом и Кристианом Хейлманном еще на заре разработки веб-приложений, то да, абсолютно, я согласитесь, занятия дадут некоторую экономию оперативной памяти…

… за исключением того, что у вас есть потенциальная возможность утечки большого количества данных, точно так же, как у Java есть тенденция к утечке данных, и у вас должна быть стратегия, обеспечивающая очистку объектов, которые возвращаются в пулы (вы *используете* пулы , для экономии памяти, верно?), или вы тщательно удаляете объекты, к которым можно получить доступ вне контекста (закрытия) одной операции одного контроллера Express. Учитывая, что Крокфорд работает в PayPal, безопасность закрытия через __dontTouchPlease__ может быть ударом по ОЗУ, на который они готовы пойти.

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