我在一组Immutable.js组件中实现React,其中包含包含对象的道具,其中之前没有使用过Immutable。
当我将所有 {someProp.someValue} 重写为 {someProp.get(“someValue”)} 时(因为Immutable没有可直接访问的道具) ,我只是想知道在对象仍然是不可变的情况下是否可以直接访问对象属性。
我想原因是,如果它们可以直接访问,它们将是可变的,因为这是javascript对象的工作方式。但是,如果不能freeze对象(当然在支持它的浏览器中),并且仍然有变异方法(.set,.map等)创建副本而不是以不可变的工作方式改变对象本身?
技术上是否可行,是否有任何图书馆都在做这样的事情?
答案 0 :(得分:0)
“技术上是否可行”
是的,您描述的实现将解决该特定问题,但Immutable不仅提供您不允许直接更改的数据结构:
Immutable
提供永久不变List
,Stack
,Map
,OrderedMap
,Set
,OrderedSet
和{{1} }}。通过使用Clojure和Scala推广的哈希映射尝试和矢量尝试进行结构共享,最大限度地减少复制或缓存数据的需要,它们在现代JavaScript虚拟机上非常高效。。{/ 1}
Record
还提供了一个惰性Immutable
,,可以有效地链接Seq
和map
等收集方法,而无需创建中间表示。创建一些filter
Seq
和Range
。
强调我的。
因此,如果您拥有大量嵌套的不可变地图和列表,并且您更改了一个元素(即:您创建了一个 new 结构,其中大部分数据相同但一个项目不同), Immutable将能够在两个数据结构之间共享大量数据,从而使操作更快,并且消耗更少的内存。
但是,这意味着Repeat
值不一定存储在数据结构的顶部,等待您访问它; Immutable必须进入内部才能找到它,因此需要someValue
。
我怀疑你可以使用Symbols(隐藏基础数据结构)和Proxies(截取属性访问者)创建一个非常酷且友好的API,但是browser support is practically non-existent。
“是否有任何图书馆已经做过这样的事情?”
目前我能想到的最接近的事是React's immutable helpers。更新语法有点嘈杂,以支持各种操作,但另一端是纯JavaScript对象和数组。
在JavaScript中处理不可变数据比在Clojure中为其设计的语言更难。但是,我们提供了一个简单的不变性辅助工具
get
,可以更轻松地处理此类数据, ,无需从根本上改变数据的表示方式
辅助类假设你传入的对象是隐式不可变的,但是没有理由你也不能deeply freeze它们。