Readonly Collections S1
- Stage: Stage 1
- Status: Active
- ECMAScript edition: —
- Synchronized: Aug 28, 2026
- 中文译文 · Source repository
This proposal addresses the lack of immutable collections in JavaScript by adding snapshot, diverge, and readOnlyView methods to all enumerable collections, along with new FixedMap and ReadOnlyMap classes. It aims to separate querying from mutation capabilities, with behavioral subtyping defined by Liskov substitutability.
The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.
proposal-readonly-collections
snapshot,diverge,readOnlyView methods for all collections
by Mark S. Miller (@erights) and Peter Hoddie (@phoddie)
Status
Presented to TC39 (Javascript standards committee), achieving stage 1.
Proposal
Currently JavaScript collections are unconditionally mutable. However, many use cases could benefit from separating the ability to query a collection from the ability to mutate it. Indeed, we have seen repeated calls for such support. To minimize cognitive load of new API, we propose the addition of only three new methods to all collections, and the addition of new collection classes whose APIs are only a subset of the existing collection abstractions. We propose these apply to all EcmaScript enumerable collections, i.e., all EcmaScript collections except WeakMap and WeakSet. We illustrate the general case using Map as a concrete example. For brevity, we refer to class-like constructors, such as Map, as if they are classes.
Where currently we have one Map class that represents the mutable variant, we would add a FixedMap and a ReadOnlyMap. We add these classes as static members of the Map class to avoid polluting the global name space. All three of these classes would support the snapshot, diverge, and readOnlyView methods proposed here. In addition, FixedMap and ReadOnlyMap would support the query-only methods of Map but not any of the methods that would mutate a map. They have precisely the same API but different behavioral contracts.
Following the Liskov substitutability principle, we consider a type to be a behavioral contract. Type B is a behavioral subtype of type A when instances of B obey A's specification of the behavior of A instances. By these criteria Map, FixedMap, and ReadOnlyMap are behavioral subtypes of a hypothetical AbstractMap, which again has exactly the API of FixedMap and ReadOnlyMap, but a weaker behavioral type that Map also obeys. In addition, FixedMap is a behavioral subtype of ReadOnlyMap At this time, we do not propose actually creating this abstract supertype AbstractMap, but rather treat it as a specification fiction.
The types in the API definitions below are stated according to these behavioral subtyping relationships.
APIs
On a suitable implementation such as Moddable's XS, the "*Fixed" versions of these collections can often be placed in ROM. This is especially valuable for data collections such as ArrayBuffer.
Shim
Readonly Collections Shim is a start on a shim of this proposal.
Related
This proposal is based on experience with E's collection classes.
