2015-10-01 3 views
2

Я реализую Immutable.js в комплекте React компонентов с реквизитами, содержащими объекты, где Immutable ранее не использовался.Неизменяемый javascript с прямым доступом к объекту

Пока я переписывал все {someProp.someValue} к {someProp.get («SomeValue»)} (с Неизменное не реквизита напрямую), доступную, я просто интересно, если это может иметь можно было получить свойства объекта напрямую, пока объект по-прежнему остается неизменным.

Я предполагаю, что причина в том, что если они имеют прямой доступ к ним, они будут изменчивыми, потому что именно так работают объекты javascript. Однако не может ли быть freeze объектов (в браузерах, поддерживающих его, конечно), и все еще есть методы мутации (.set, .map и т. Д.), Создавая копии вместо того, чтобы изменять сам объект так же, как Неизменяемая работа?

Это технически возможно, и есть ли какая-нибудь библиотека, делающая что-то вроде этого allready?

+0

вы можете заморозить простой объект и получить доступ к нему в обычном режиме. вы также можете создать обертку вокруг своей неизменяемой структуры, используя Object.defineProperty для создания геттеров, которые вызывают .get() внутри. – dandavis

ответ

0

«Это технически возможно»

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

Immutable Предоставляет постоянный неизменяемый List, Stack, Map,, Set, OrderedSet и Record. Это высокоэффективны для современных JavaScript-виртуальных машин, используя структурный обмен через попытки хэш-карт и векторные попытки, которые популяризируются Clojure и Scala, сводя к минимуму необходимость копировать или кэшировать данные.

Immutable также обеспечивает ленивый Seq, что позволяет эффективно цепочки методов сбора, как map и filter без создания промежуточных представлений. Создайте Seq с Range и Repeat.

Emphasis mine.

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

Однако это означает, что значение someValue не обязательно хранится в верхней части структуры данных, ожидая, что вы получите к нему доступ; Неизменяемый должен проникнуть внутрь, чтобы найти его для вас, поэтому необходимо, чтобы get.

Я подозреваю, что вы могли бы создать очень крутой и дружественный API, используя Symbols (чтобы скрыть основные структуры данных) и Proxies (перехват proprety аксессоров), но browser support is practically non-existent.

«И есть ли какая-либо библиотека, которая уже делает что-то подобное?«

Ближайшая вещь, о которой я могу думать в данный момент, - React's immutable helpers. Синтаксис обновления немного шумный, чтобы поддерживать широкий диапазон операций, но то, что вы выбрали на другом конце, это простые объекты и массивы JavaScript .

Работа с неизменными данными в JavaScript является более сложным, чем в языках, предназначенные для этого, как Clojure. Тем не менее, мы предоставили простую помощник неизменности, update(), что делает дело с этим типом данных намного проще, без кардинально меняется, как ваши данные представлены.

Помощник рода предполагает объектов вы передаете в неявно неизменны, но нет никаких причин, вы не могли deeply freeze их.

+0

Подробнее о Proxies: для этого есть очень крошечный и молодой [lib] (https://github.com/Legitcode/immutable-proxy) - хорошее место для начала. Кроме того, существует [ограниченный, но эффективный полиполк для прокси] (https://github.com/GoogleChrome/proxy-polyfill) –

Смежные вопросы