Immutable.js обеспечивает это, но требует, чтобы вы использовали только типы и примитивы immutable.Это будет означать использование типов Record
Immutable вместо классов *.Ваш пример в этом случае будет выглядеть так:
const { Record, Map } = require('immutable');
const Coord = Record({ a: 0, b: 0 }); // Record fields have default values
const valueMap = new Map().set(Coord(1, 1), `A set value`);
console.log(valueMap.get(Coord(1, 1))); // Logs "A set value"
Immutable.js может быть не совсем тем, что вы хотите, потому что все его коллекции, ну, в общем, неизменяемы.Каждая операция возвращает новую коллекцию, а не изменяет оригинал.К счастью, благодаря магии структурного разделения, это намного быстрее, чем можно было ожидать.
Я видел несколько альтернатив, но все они были реализованы неправильно (например, предполагая уникальность хэшей,строки вашего toString
примера) или имели серьезные сложности или проблемы с производительностью при составлении карт.Например, Immutable.js позволяет использовать карту (или набор, или список, или карту наборов и т. Д.) В качестве ключа на другой карте.Несколько библиотек, которые я видел, которые правильно принимают хэш и функцию равенства в качестве аргументов для карты, либо пропускают эту сложность до конечного пользователя, либо имеют гораздо худшую производительность в этом случае.Наконец, библиотеки, которые зависят от значений хеш-функции, могут столкнуться с проблемами, если хранимый объект видоизменяется, поэтому использование библиотеки, обеспечивающей неизменность, может помочь избежать появления огнестрельного оружия.
Если Immutable.js вам не нравится,Есть несколько похожих библиотек. Mori был оригинальной библиотекой с неизменяемой структурой в JS и предоставляет несколько структур данных с семантикой значений (включая карты), но основан на Clojure и имеет очень неидиоматический интерфейс для JavaScript.В обеих этих библиотеках используются сопоставления массивов хеш-кодов для обеспечения эффективной реализации неизменяемых структур, и этот тип доступен в hamt.js .Тем не менее, Hamt очень прост и обеспечивает более сложный и менее сложный интерфейс, чем предыдущие два.
* Технически вы можете использовать свой собственный класс, реализуя Интерфейс Value Object и добавление методов equals
и hashCode
в ваши классы, но я считаю, что вы можете столкнуться с проблемами, если ваши объекты видоизменяются в то время как внутри коллекций Immutable.js, поэтому использование Records, вероятно, безопаснеев любом случае.