JavaScript Mapping for Dictionaries
Here is the definition of our EmployeeMap once more:
dictionary<int, Employee> EmployeeMap;
In the JavaScript mapping, dictionaries using a JavaScript built-in type as the key type are mapped to the JavaScript Map type. This is true for all Slice built-in types except long, the Slice-to-JavaScript compiler generates a type alias for Map with the same name as the Slice dictionary, the generated code is equivalent to:
EmployeeMap = Map;
class EmployeeMap extends Map<number, Employee>{}
const em = new EmployeeMap(); const e = new Employee(); e.number = 31; e.firstName = "James"; e.lastName = "Gosling"; em.set(e.number, e);
In JavaScript using EmployeeMap
allows to better declare our intention in the code but as far as the Ice run-time is concerned using Map
will be equally fine, the same goes for TypeScript using EmployeeMap
is convenient but as far as the compiler is concerned using a type that implements Map<number, Employee>
will be fine
For cases where the key type does not correspond with a JavaScript built-in type, the dictionary is mapped to Ice.HashMap
. This is true for Slice dictionaries where the key type is long
or a Slice structure that qualifies as a legal dictionary key:
dictionary<long, Employee> EmployeeMap;
In these cases an extra constructor is generated that initializes the Ice.HashMap
with the desired comparison operator.
class EmployeeMap extends Ice.HashMap { constructor(h) { super(h || keysEqual); } }
class EmployeeMap extends Ice.HashMap<Ice.Long, Employee>{}
const em = new EmployeeMap(); const e = new Employee(); e.number = new Ice.Long(31); e.firstName = "James"; e.lastName = "Gosling"; em.set(e.number, e);
The mapping for dictionaries in TypeScript is the same, the only difference is that the TypeScript compiler will enforce the Key and Value types when using the TypeScript definitions generated by Slice-to-JavaScript compiler.
Ice.HashMap supports the same API as the standard JavaScript Map object. It provides the following additional properties and functions:
HashMap.prototype.constructor(keyComparator, valueComparator)
This version of the constructor accepts optional comparator functions that the map uses to compare keys and values for equality. If you instantiate a map directly usingnew Ice.HashMap()
without specifying comparator functions, the default comparators use the===
operator to compare keys and values. As an example, the following map compares its keys and values usingequals
methods:JavaScriptfunction compareEquals(a, b) { return a.equals(b); } const m = new Ice.HashMap(compareEquals, compareEquals);
ThevalueComparator
function is only used when comparing two maps for equality.The type-specific constructor generated for a Slice dictionary supplies comparator functions appropriate for its key and value types.
HashMap.prototype.equals(other, valueComparator)
Returns true if this map compares equal to the given map, false otherwise. You can optionally supply a function forvalueComparator
that the map uses when comparing values; this function takes precedence over the comparator supplied to the map's constructor.
HashMap.prototype.clone()
Returns a shallow copy of the map.
Legal key types for Ice.HashMap
include JavaScript's primitive types along with null
, NaN
, and any object that defines a hashCode
method. The generated code for a Slice structure that qualifies as a legal dictionary key type includes a hashCode
method. Suppose we define another dictionary type:
dictionary<Employee, string> EmployeeDeptMap;
The Slice compiler generates a constructor function equivalent to the following code:
class EmployeeDeptMap extends Ice.HashMap { constructor(h) { const keyComparator = ...; const valueComparator = ...; super(h || keyComparator, valueComparator); } }
class EmployeeDeptMap extends Ice.HashMap<Employee, string> { }
Since the key is a user-defined structure type, the map requires a comparator that properly compares keys. Instantiating a map using new EmployeeDeptMap
automatically sets the comparators, whereas calling new Ice.HashMap
in this case would require you to supply your own comparators.
Slice dictionaries that map to a HashMap must be instantiated using the generated constructor.
Notes
- Attempting to use the
map[key] = value
syntax to add an element to the map will not have the desired effect; you must use theset
function instead.