Keyed collections - JavaScript | MDN

archived 16 Jan 2018 22:43:33 UTC
MDN wants to learn about developers like you: https://qsurvey.mozilla.com/s3/MDN-dev-survey-2018-1
This chapter introduces collections of data which are ordered by a key; Map and Set objects contain elements which are iterable in the order of insertion.

Maps

Map object

ECMAScript 2015 introduces a new data structure to map values to values. A Map object is a simple key/value map and can iterate its elements in insertion order.
The following code shows some basic operations with a Map. See also the Map reference page for more examples and the complete API. You can use a for...of loop to return an array of [key, value] for each iteration.
var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
sayings.size; // 3
sayings.get('fox'); // undefined
sayings.has('bird'); // false
sayings.delete('dog');
sayings.has('dog'); // false

for (var [key, value] of sayings) {
  console.log(key + ' goes ' + value);
}
// "cat goes meow"
// "elephant goes toot"

sayings.clear();
sayings.size; // 0

Object and Map compared

Traditionally, objects have been used to map strings to values. Objects allow you to set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. Map objects, however, have a few more advantages that make them better maps.
  • The keys of an Object are Strings, where they can be of any value for a Map.
  • You can get the size of a Map easily while you have to manually keep track of size for an Object.
  • The iteration of maps is in insertion order of the elements.
  • An Object has a prototype, so there are default keys in the map. (this can be bypassed using map = Object.create(null)).
These three tips can help you to decide whether to use a Map or an Object:
  • Use maps over objects when keys are unknown until run time, and when all keys are the same type and all values are the same type.
  • Use maps in case if there is a need to store primitive values as keys because object treats each key as a string whether it's a number value, boolean value or any other primitive value.
  • Use objects when there is logic that operates on individual elements.

WeakMap object

The WeakMap object is a collection of key/value pairs in which the keys are objects only and the values can be arbitrary values. The object references in the keys are held weakly, meaning that they are a target of garbage collection (GC) if there is no other reference to the object anymore. The WeakMap API is the same as the Map API.
One difference to Map objects is that WeakMap keys are not enumerable (i.e., there is no method giving you a list of the keys). If they were, the list would depend on the state of garbage collection, introducing non-determinism.
For more information and example code, see also "Why WeakMap?" on the WeakMap reference page.
One use case of WeakMap objects is to store private data for an object or to hide implementation details. The following example is from Nick Fitzgerald's blog post "Hiding Implementation Details with ECMAScript 6 WeakMaps". The private data and methods belong inside the object and are stored in the privates WeakMap object. Everything exposed on the instance and prototype is public; everything else is inaccessible from the outside world because privates is not exported from the module
const privates = new WeakMap();

function Public() {
  const me = {
    // Private data goes here
  };
  privates.set(this, me);
}

Public.prototype.method = function() {
  const me = privates.get(this);
  // Do stuff with private data in `me`...
};

module.exports = Public;

Sets

Set object

Set objects are collections of values. You can iterate its elements in insertion order. A value in a Set may only occur once; it is unique in the Set's collection.
The following code shows some basic operations with a Set. See also the Set reference page for more examples and the complete API.
var mySet = new Set();
mySet.add(1);
mySet.add('some text');
mySet.add('foo');

mySet.has(1); // true
mySet.delete('foo');
mySet.size; // 2

for (let item of mySet) console.log(item);
// 1
// "some text"

Converting between Array and Set

You can create an Array from a Set using Array.from or the spread operator. Also, the Set constructor accepts an Array to convert in the other direction. Note again that Set objects store unique values, so any duplicate elements from an Array are deleted when converting.
Array.from(mySet);
[...mySet2];

mySet2 = new Set([1, 2, 3, 4]);

Array and Set compared

Traditionally, a set of elements has been stored in arrays in JavaScript in a lot of situations. The new Set object, however, has some advantages:
  • Checking whether an element exists in a collection using indexOf for arrays is slow.
  • Set objects let you delete elements by their value. With an array you would have to splice based on an element's index.
  • The value NaN cannot be found with indexOf in an array.
  • Set objects store unique values; you don't have to keep track of duplicates by yourself.

WeakSet object

WeakSet objects are collections of objects. An object in the WeakSet may only occur once; it is unique in the WeakSet's collection and objects are not enumerable.
The main differences to the Set object are:
  • In contrast to Sets, WeakSets are collections of objects only and not of arbitrary values of any type.
  • The WeakSet is weak: References to objects in the collection are held weakly. If there is no other reference to an object stored in the WeakSet, they can be garbage collected. That also means that there is no list of current objects stored in the collection. WeakSets are not enumerable.
The use cases of WeakSet objects are limited. They will not leak memory so it can be safe to use DOM elements as a key and mark them for tracking purposes, for example.

Key and value equality of Map and Set

Both the key equality of Map objects and the value equality of Set objects, are based on the "same-value-zero algorithm":
  • Equality works like the identity comparison operator ===.
  • -0 and +0 are considered equal.
  • NaN is considered equal to itself (contrary to ===).

Document Tags and Contributors

 Last updated by: jamesray1,
Related Topics
  1. JavaScript
  2. Tutorials:
  3. Complete beginners
    1. JavaScript basics
    2. JavaScript first steps
    3. JavaScript building blocks
    4. Introducing JavaScript objects
  4. JavaScript Guide
    1. Introduction
    2. Grammar and types
    3. Control flow and error handling
    4. Loops and iteration
    5. Functions
    6. Expressions and operators
    7. Numbers and dates
    8. Text formatting
    9. Regular expressions
    10. Indexed collections
    11. Keyed collections
    12. Working with objects
    13. Details of the object model
    14. Iterators and generators
    15. Meta programming
  5. Intermediate
    1. Introducing JavaScript objects
    2. Client-side web APIs
    3. A re-introduction to JavaScript
    4. JavaScript data structures
    5. Equality comparisons and sameness
    6. Closures
  6. Advanced
    1. Inheritance and the prototype chain
    2. Strict mode
    3. JavaScript typed arrays
    4. SIMD types
    5. Memory Management
    6. Concurrency model and Event Loop
  7. References:
  8. Built-in objects
    1. Array
    2. ArrayBuffer
    3. AsyncFunction
    4. Atomics
    5. Boolean
    6. DataView
    7. Date
    8. Error
    9. EvalError
    10. Float32Array
    11. Float64Array
    12. Function
    13. Generator
    14. GeneratorFunction
    15. Infinity
    16. Int16Array
    17. Int32Array
    18. Int8Array
    19. InternalError
    20. Intl
    21. Intl.Collator
    22. Intl.DateTimeFormat
    23. Intl.NumberFormat
    24. Intl.PluralRules
    25. JSON
    26. Map
    27. Math
    28. NaN
    29. Number
    30. Object
    31. Promise
    32. Proxy
    33. RangeError
    34. ReferenceError
    35. Reflect
    36. RegExp
    37. SIMD
    38. SIMD.Bool16x8
    39. SIMD.Bool32x4
    40. SIMD.Bool64x2
    41. SIMD.Bool8x16
    42. SIMD.Float32x4
    43. SIMD.Float64x2
    44. SIMD.Int16x8
    45. SIMD.Int32x4
    46. SIMD.Int8x16
    47. SIMD.Uint16x8
    48. SIMD.Uint32x4
    49. SIMD.Uint8x16
    50. Set
    51. SharedArrayBuffer
    52. String
    53. Symbol
    54. SyntaxError
    55. TypeError
    56. TypedArray
    57. URIError
    58. Uint16Array
    59. Uint32Array
    60. Uint8Array
    61. Uint8ClampedArray
    62. WeakMap
    63. WeakSet
    64. WebAssembly
    65. decodeURI()
    66. decodeURIComponent()
    67. encodeURI()
    68. encodeURIComponent()
    69. escape()
    70. eval()
    71. isFinite()
    72. isNaN()
    73. null
    74. parseFloat()
    75. parseInt()
    76. undefined
    77. unescape()
    78. uneval()
  9. Expressions & operators
    1. Arithmetic operators
    2. Array comprehensions
    3. Assignment operators
    4. Bitwise operators
    5. Comma operator
    6. Comparison operators
    7. Conditional (ternary) Operator
    8. Destructuring assignment
    9. Expression closures
    10. Generator comprehensions
    11. Grouping operator
    12. Legacy generator function expression
    13. Logical Operators
    14. Object initializer
    15. Operator precedence
    16. Pipeline operator
    17. Property accessors
    18. Spread syntax
    19. async function expression
    20. await
    21. class expression
    22. delete operator
    23. function expression
    24. function* expression
    25. in operator
    26. instanceof
    27. new operator
    28. new.target
    29. super
    30. this
    31. typeof
    32. void operator
    33. yield
    34. yield*
  10. Statements & declarations
    1. Legacy generator function
    2. async function
    3. block
    4. break
    5. class
    6. const
    7. continue
    8. debugger
    9. default
    10. do...while
    11. empty
    12. export
    13. for
    14. for each...in
    15. for...in
    16. for...of
    17. function declaration
    18. function*
    19. if...else
    20. import
    21. label
    22. let
    23. return
    24. switch
    25. throw
    26. try...catch
    27. var
    28. while
    29. with
  11. Functions
    1. Arguments object
    2. Arrow functions
    3. Default parameters
    4. Method definitions
    5. Rest parameters
    6. getter
    7. setter
  12. Classes
    1. constructor
    2. extends
    3. static
  13. Errors
    1. Error: Permission denied to access property "x"
    2. InternalError: too much recursion
    3. RangeError: argument is not a valid code point
    4. RangeError: invalid array length
    5. RangeError: invalid date
    6. RangeError: precision is out of range
    7. RangeError: radix must be an integer
    8. RangeError: repeat count must be less than infinity
    9. RangeError: repeat count must be non-negative
    10. ReferenceError: "x" is not defined
    11. ReferenceError: assignment to undeclared variable "x"
    12. ReferenceError: can't access lexical declaration`X' before initialization
    13. ReferenceError: deprecated caller or arguments usage
    14. ReferenceError: invalid assignment left-hand side
    15. ReferenceError: reference to undefined property "x"
    16. SyntaxError: "0"-prefixed octal literals and octal escape seq. are deprecated
    17. SyntaxError: "use strict" not allowed in function with non-simple parameters
    18. SyntaxError: "x" is a reserved identifier
    19. SyntaxError: JSON.parse: bad parsing
    20. SyntaxError: Malformed formal parameter
    21. SyntaxError: Unexpected token
    22. SyntaxError: Using //@ to indicate sourceURL pragmas is deprecated. Use //# instead
    23. SyntaxError: a declaration in the head of a for-of loop can't have an initializer
    24. SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
    25. SyntaxError: for-in loop head declarations may not have initializers
    26. SyntaxError: function statement requires a name
    27. SyntaxError: identifier starts immediately after numeric literal
    28. SyntaxError: illegal character
    29. SyntaxError: invalid regular expression flag "x"
    30. SyntaxError: missing ) after argument list
    31. SyntaxError: missing ) after condition
    32. SyntaxError: missing : after property id
    33. SyntaxError: missing ; before statement
    34. SyntaxError: missing = in const declaration
    35. SyntaxError: missing ] after element list
    36. SyntaxError: missing formal parameter
    37. SyntaxError: missing name after . operator
    38. SyntaxError: missing variable name
    39. SyntaxError: missing } after function body
    40. SyntaxError: missing } after property list
    41. SyntaxError: redeclaration of formal parameter "x"
    42. SyntaxError: return not in function
    43. SyntaxError: test for equality (==) mistyped as assignment (=)?
    44. SyntaxError: unterminated string literal
    45. TypeError: "x" has no properties
    46. TypeError: "x" is (not) "y"
    47. TypeError: "x" is not a constructor
    48. TypeError: "x" is not a function
    49. TypeError: "x" is not a non-null object
    50. TypeError: "x" is read-only
    51. TypeError: More arguments needed
    52. TypeError: can't access dead object
    53. TypeError: can't define property "x": "obj" is not extensible
    54. TypeError: can't delete non-configurable array element
    55. TypeError: can't redefine non-configurable property "x"
    56. TypeError: cannot use 'in' operator to search for 'x' in 'y'
    57. TypeError: cyclic object value
    58. TypeError: invalid Array.prototype.sort argument
    59. TypeError: invalid arguments
    60. TypeError: invalid assignment to const "x"
    61. TypeError: property "x" is non-configurable and can't be deleted
    62. TypeError: setting getter-only property "x"
    63. TypeError: variable "x" redeclares argument
    64. URIError: malformed URI sequence
    65. Warning: -file- is being assigned a //# sourceMappingURL, but already has one
    66. Warning: 08/09 is not a legal ECMA-262 octal constant
    67. Warning: Date.prototype.toLocaleFormat is deprecated
    68. Warning: JavaScript 1.6's for-each-in loops are deprecated
    69. Warning: String.x is deprecated; use String.prototype.x instead
    70. Warning: expression closures are deprecated
    71. Warning: unreachable code after return statement
    72. X.prototype.y called on incompatible type
  14. Misc
    1. JavaScript technologies overview
    2. Lexical grammar
    3. JavaScript data structures
    4. Enumerability and ownership of properties
    5. Iteration protocols
    6. Strict mode
    7. Transitioning to strict mode
    8. Template literals
    9. Deprecated features
  15. New in JavaScript
    1. ECMAScript 2015 support in Mozilla
    2. ECMAScript 5 support in Mozilla
    3. ECMAScript Next support in Mozilla
    4. Firefox JavaScript changelog
    5. New in JavaScript 1.1
    6. New in JavaScript 1.2
    7. New in JavaScript 1.3
    8. New in JavaScript 1.4
    9. New in JavaScript 1.5
    10. New in JavaScript 1.6
    11. New in JavaScript 1.7
    12. New in JavaScript 1.8
    13. New in JavaScript 1.8.1
    14. New in JavaScript 1.8.5
  16. Documentation:
  17. Useful lists
    1. All pages index
    2. Methods index
    3. Properties index
    4. Pages tagged "JavaScript"
  18. Contribute
    1. JavaScript doc status
    2. The MDN project

Thanks! Please check your inbox to confirm your subscription.

If you haven’t previously confirmed a subscription to a Mozilla-related newsletter you may have to do so. Please check your inbox or your spam filter for an email from us.
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%