ES6+ Features: Collections
Relevant source files
The following files were used as context for generating this wiki page:
The Jurassic engine provides a robust and standards-compliant implementation of the ECMAScript 6 (ES6) collection types: Map, Set, WeakMap, and WeakSet. These built-in objects offer more specialized and efficient data management capabilities compared to plain JavaScript objects or arrays.
The implementation status for these features is nearly complete, indicating a mature and reliable feature set within the engine. For example, Map and Set pass 18 out of 19 compatibility tests, while WeakMap and WeakSet pass 11/12 and 10/11 tests, respectively. This high level of compliance ensures that developers can rely on behavior that aligns closely with the ECMAScript standard.
Sources: README.md:61-64
Core Collections (Map and Set)
The core collections, Map and Set, provide ordered collections of data. Unlike their "weak" counterparts, they hold strong references to their elements, preventing garbage collection as long as the elements exist within the collection.
Map
A Map object holds key-value pairs and remembers the original insertion order of the keys. Any value (both objects and primitive values) may be used as either a key or a value.
Internal Architecture
The MapInstance in Jurassic uses two underlying .NET data structures to manage its data and maintain insertion order:
Dictionary<object, LinkedListNode<KeyValuePair<object, object>>>: A dictionary for fast key-based lookups (O(1)average time complexity forget,has, anddelete). The dictionary's value is a node in the linked list.LinkedList<KeyValuePair<object, object>>: A doubly-linked list that stores the key-value pairs. This structure preserves the insertion order, which is crucial for iterators (keys(),values(),entries(), andforEach()).
This dual-structure approach provides both fast lookups and ordered iteration. A special behavior is the handling of -0 as a key, which is normalized to +0 to conform to the ECMAScript specification.
Sources: Jurassic/Library/Map/MapInstance.cs:23-24, Jurassic/Library/Map/MapInstance.cs:113-115, Test Suite Runner/Kangax/compat-table.json:3013-3022
The following diagram illustrates the class structure for MapInstance.
API and Behavior
The public API for Map is exposed to the JavaScript engine via ClrStubFunction wrappers.
| Method/Property | Description |
|---|---|
get size | Returns the number of key/value pairs in the Map object. |
set(key, value) | Sets the value for the key in the Map object. Returns the Map object. |
get(key) | Returns the value associated with the key, or undefined if the key can't be found. |
has(key) | Returns a boolean asserting whether a value has been associated with the key. |
delete(key) | Removes the key and its associated value. Returns true if an element existed and was removed. |
clear() | Removes all key-value pairs from the Map object. |
entries() | Returns a new Iterator object that contains an array of [key, value] for each element. |
keys() | Returns a new Iterator object that contains the keys for each element. |
values() | Returns a new Iterator object that contains the values for each element. |
forEach(callback, [thisArg]) | Executes a provided function once for each key/value pair in the Map object, in insertion order. |
Sources: Jurassic/Library/Map/MapInstance.g.cs:12-25
Set
A Set object lets you store unique values of any type, whether primitive values or object references. It also maintains insertion order.
Internal Architecture
The SetInstance implementation is very similar to MapInstance, using a Dictionary for fast lookups and a LinkedList to preserve insertion order.
Dictionary<object, LinkedListNode<object>>: ForO(1)average time complexity onhas,add, anddelete.LinkedList<object>: To maintain the ordered list of values for iteration.
Like Map, Set also normalizes -0 values to +0 to ensure uniqueness as per the specification.
Sources: Jurassic/Library/Set/SetInstance.cs:22-23, Jurassic/Library/Set/SetInstance.cs:91, Test Suite Runner/Kangax/compat-table.json:3157-3166
The diagram below shows the class structure for SetInstance.
Sources: Jurassic/Library/Set/SetInstance.cs
API and Behavior
| Method/Property | Description |
|---|---|
get size | Returns the number of values in the Set object. |
add(value) | Appends a new element with the given value to the Set. Returns the Set object. |
has(value) | Returns a boolean asserting whether an element is present with the given value. |
delete(value) | Removes the specified element from the Set object. Returns true if an element existed and was removed. |
clear() | Removes all elements from the Set object. |
entries() | Returns a new Iterator object that contains an array of [value, value] for each element. |
keys() | An alias for values(). Returns a new Iterator object that contains the values for each element. |
values() | Returns a new Iterator object that contains the values for each element. |
forEach(callback, [thisArg]) | Executes a provided function once for each value in the Set object, in insertion order. |
Sources: Jurassic/Library/Set/SetInstance.cs:88-182
Weak Collections (WeakMap and WeakSet)
Weak collections are designed for storing object data weakly. The keys of WeakMap and values of WeakSet must be objects. Primitives cannot be used. The "weak" reference means that if no other strong reference to an object exists, it can be garbage collected, even if it is in a weak collection.
WeakMap
A WeakMap is a collection of key/value pairs where the keys are weakly referenced.
Internal Architecture
WeakMapInstance is implemented using the .NET System.Runtime.CompilerServices.ConditionalWeakTable<ObjectInstance, object>. This class is specifically designed for associating data with an object, where the data's lifetime is tied to the object's lifetime. This perfectly matches the requirements for WeakMap.
Because the entries can be garbage collected at any time, WeakMap instances are not enumerable. This means there are no forEach, keys, values, or entries methods, and there is no size property.
Sources: Jurassic/Library/WeakMap/WeakMapInstance.cs:20, Test Suite Runner/Kangax/compat-table.json:3300-3309
The following diagram shows the WeakMapInstance class structure.
API and Behavior
| Method | Description |
|---|---|
set(key, value) | Sets the value for the key in the WeakMap object. The key must be an object. |
get(key) | Returns the value associated with the key, or undefined if the key can't be found. |
has(key) | Returns a boolean indicating whether an element with the specified key exists. |
delete(key) | Removes the specified element from a WeakMap object. |
Sources: Jurassic/Library/WeakMap/WeakMapInstance.cs:58-94
A notable behavior is that methods like has, get, and delete accept primitive values as arguments but will always return false or undefined because only objects can be keys.
Sources: Test Suite Runner/Kangax/compat-table.json:3310-3316
WeakSet
A WeakSet is a collection of objects, where the objects are weakly referenced.
Internal Architecture
Like WeakMap, the WeakSetInstance is implemented using System.Runtime.CompilerServices.ConditionalWeakTable<ObjectInstance, object>. In this case, the value stored in the ConditionalWeakTable is a dummy object, as WeakSet only cares about the presence of the key object.
For the same reasons as WeakMap, WeakSet is not enumerable and lacks a size property and iterator methods.
Sources: Jurassic/Library/WeakSet/WeakSetInstance.cs:19, Test Suite Runner/Kangax/compat-table.json:3391-3400
The diagram below shows the WeakSetInstance class structure.
API and Behavior
| Method | Description |
|---|---|
add(value) | Appends a new object to the WeakSet. |
has(value) | Returns a boolean indicating whether an element with the specified value exists. |
delete(value) | Removes the specified element from a WeakSet object. |
Sources: Jurassic/Library/WeakSet/WeakSetInstance.cs:51-75
Like WeakMap, the has and delete methods accept primitives but always return false, as only objects can be members of a WeakSet.
Sources: Test Suite Runner/Kangax/compat-table.json:3401-3406
Summary
The Jurassic engine provides a full-featured and standards-compliant implementation of ES6 collections. Map and Set offer ordered collections with a rich API for iteration and management, backed by efficient .NET data structures. WeakMap and WeakSet provide specialized collections for weakly holding object references, correctly leveraging the .NET ConditionalWeakTable for garbage-collection-friendly caching and metadata association. The high pass rate in compatibility tests confirms their reliability for use in any application integrating the Jurassic engine.