А что в такой ситуации мешает просто создать объект
Потому что в Java, C# нельзя написать такое:
export const singleton = {name: "foo"}; // Полноценный синглтон для JS
Импортируются и экспортируются лишь классы. Создать глобальную переменную, которая будет хранить глобальное состояние, которую потом можно импортировать в разных файлах (классах) — нельзя.
Следовательно, нужен класс, у которого будет статическое поле, содержащие это глобальное состояние.
Т.к. экземпляр класса должен быть только один, кем он должен быть создан? А создается он "автоматически" — непосредственно при загрузке класса в статическом блоке инициализации класса (да, в JS это тоже есть), и в качестве дополнительной меры предосторожности, чтобы никто не создал второй экземпляр, конструктор делается приватным — недоступным для любого кода, который будет работать с этим классом.
Какие здесь преимущества именно в создании класса?
Функционально — никакие.
Код будет выглядеть привычнее для людей знакомых с Java и C#.
Ради формальности, все-таки да, отличие есть, и оно в том, что в случает использования класса, тот объект будет экземпляром класса синглтон, и еще один экземпляр этого класса создать не получится. Можно даже проверку сделать с помощью
instanceof
, чтобы удостовериться, что передается именно инстанс того класса, который может быть лишь в одном экземпляре, а не какой-то другой объект. А если это "просто объект" — ты сможешь подсунуть полную "копию" без каких-либо проблем, создав ее с помощью литеральной записи.