JavaScript Mapping for Dictionaries

Here is the definition of our EmployeeMap once more:

Slice
dictionary<long, Employee> EmployeeMap;

In the JavaScript mapping, all dictionaries are instances of the Ice.HashMap type. The mapping also generates a type-specific constructor with the same name as the dictionary. For example:

JavaScript
var em = new EmployeeMap();

var e = new Employee();
e.number = new Ice.Long(31);
e.firstName = "James";
e.lastName = "Gosling";

em.set(e.number, e);

HashMap objects support the following properties and functions:

  • HashMap(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 using new 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 using equals methods:

    JavaScript
    function compareEquals(a, b) { return a.equals(b); }
    var m = new Ice.HashMap(compareEquals, compareEquals);
    

    The valueComparator 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(h)
    This version of the constructor accepts an optional HashMap object from which all entries are (shallow) copied. The new map inherits the comparator functions of the original.
  • size
    The size property indicates how many entries are currently in the map.
  • entries
    The entries property holds the head of a linked list that can be used to traverse all map entries.

  • get(key)
    Returns the value associated with the given key, or undefined if no entry has a matching key.
  • set(key, value)
    Adds a new entry to the map having the given key and value. Always returns undefined.
  • has(key)
    Returns true if the map contains an entry with a matching key, or false otherwise.
  • delete(key)
    Removes the entry associated with the given key. Returns the entry's current value if a match was found, or undefined otherwise.
  • clear()
    Removes all entries in the current map.
  • keys()
    Returns an array containing all keys in an unspecified order.
  • values()
    Returns an array containing all values in an unspecified order.
  • forEach(fn, thisArg)
    Iterates over the entries in the map in an unspecified order, calling the given function once for each entry. The optional thisArg parameter is used as this when executing the function. The arguments to the function are key and value, representing the key and value of each element.
  • equals(other, valueComparator)
    Returns true if this map compares equal to the given map, false otherwise. You can optionally supply a function for valueComparator that the map uses when comparing values; this function takes precedence over the comparator supplied to the map's constructor.
  • clone()
    Returns a shallow copy of the map.

Legal key types for HashMap include JavaScript's primitive types along with nullNaN, 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:

Slice
dictionary<Employee, string> EmployeeDeptMap;

The Slice compiler generates a constructor function equivalent to the following code:

JavaScript
var EmployeeDeptMap = function(h)
{
    var keyComparator = ...;
    var valueComparator = ...;
    return new Ice.HashMap(h || keyComparator, valueComparator);
};

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.

Ice applications should always instantiate a Slice dictionary using the generated constructor.

It is not possible to use JavaScript's native for..in syntax to iterate over the map's entries. In addition to the forEach method described above, the map also maintains an unordered linked list of its entries that you can iterate through as shown below:

JavaScript
var em = new EmployeeMap();
// ...
for(var e = em.entries; e !== null; e = e.next)
{
    var employeeNum = e.key;
    var employee = e.value;
    ...
}

Each entry object supports the read-only properties keyvalue and next.

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 the set function instead.
  • The Ice run time validates the elements of a dictionary to ensure that they are compatible with the declared type; an Error exception is raised if an incompatible type is encountered.
  • The HashMap API is largely compatible with the draft EcmaScript 6 Map type, but there are also some differences between the two. Ice for JavaScript may replace HashMap with the standard Map when it is widely supported.

See Also