Map.prototype.of()

# Renki Ivanko (8 years ago)

Maps are the preferred data structure to POJOs in modern JS, but initializing them is comparatively cumbersome:

new Map(Object.entries({a: 1, b: 2, 3: 4}))
new Map([['a', 1], ['b', 2], [3, 4]])
new Map().set('a', 1).set('b', 2).set(3, 4)

The Object.entries() syntax only works for string keys and changes ordering with number keys (Object.keys({a: 1, 2: 3}) = ['2', 'a']).

The key/value pair list syntax is the most concise but the trailing [[ ]] brackets make it hard to spot missing/extra brackets, especially if the keys/values are array literals.

The Map#set() syntax is the most verbose if there's many pairs, but otherwise may be the best approach.

Verbosity is a problem with all of these, and it's been suggested previously to add a new literal syntax to make using Maps more convenient: esdiscuss.org/topic/map-literal

It's not a clear-cut solution, however, since not all languages even have collection literal notations, and adding a new one to JS would make it have two partially overlapping ones; making Map literals borrow syntax from Object literals would make it confusing (not least because of the Object literal notation extensions like accessors and method shorthand that wouldn't apply to maps) and there aren't many good options for a new syntax. For example, Ruby Hashes use { key => value } and Scala maps use Map(key -> value), but the arrow notation is already used by arrow

functions. C#6 added ... { [key] = value }, but anything with extra brackets is not much better than the existing syntax.

A solution that would largely deal with the verbosity and the extra outer brackets would be to borrow idea of the Array#of() method:

Map.of(['a', 1], ['b', 2], [3, 4])

Same as Array#of(), this adds a method for what the constructor should have been (variadic and not requiring new). The same would also work for initializing sets:

Set.of(1, 2, 3)

It's a small difference, but it also is a relatively trivial change and adds symmetry with Array. Shimming it is as simple as:

Map.of = (...args) => new Map(args)

Set.of = (...args) => new Set(args)