Why use JavaScript/ECMAScript 2015 Maps and Sets if possible

Before ECMAScript 2015 maps and sets have been emulated in JavaScript by instantiation a new empty object and adding properties. The property name acts as the key and the property value represents the value.

The example below shows an object used as a map in action. In the console log the message will be: “black”.

var examplePseudoMap = {};
examplePseudoMap['dark'] ='black';
console.log(examplePseudoMap['dark']);

Since ECMAScript 2015 JavaScript provides several build in collection types. The same example from above with the use of the map looks like the following:

var exampleMap = new Map();
exampleMap.set('dark','black');
console.log(exampleMap.get('dark'));

One issue with the pre ECMAScript 2015 emulated map and set approach is, that it is possible to have key/property name collisions with the build in properties and methods of the object. To make this problem even more cumbersome different JavaScript runtime environments have different build in properties and methods on the root object. For instance Firefox object owns a method “watch” while the Internet Explorer object don’t have such a method.

For instance within your data model you have a key value pair with the key “watch”. If this pair exists in a map/set a function must be called. Now it’s depending on the runtime environment, if the key value pair has been added to the emulated map and how the programm evaluates the existing of the key value pair.

If the “watch” key value pair has not been added into the emulated map and the evaluation of the is done like this:

var examplePseudoMap = {};
console.log(examplePseudoMap['watch'] !== undefined);

The result in

  • Firefox is always true, because the watch property does always exists on an object
  • Internet Explorer is false, because the watch property doesn’t exists on an object

The result in Firefox from a functional point of view is wrong in this use case. The programm will execute the implemented logic for the case that the data model “watch” key value pair has been added to the examplePseudoMap.

To resolve this problem when using emulated set maps in JavaScript is: It is always necessary to check the existance of the property by using the method: hasOwnProperty. This method checks if the property is an inherited or directly owned property. If the property is a directly owned property it returns true otherwise false.

var pseudoMap = {};
pseudoMap['dark'] ='black';
console.log(pseudoMap.hasOwnProperty('dark')); //returns true;
console.log(pseudoMap.hasOwnProperty('watch')); //returns false;
examplePseudoMap['watch'] ='it'; // now watch is a direct property
console.log(pseudoMap.hasOwnProperty('watch')); //now returns true;

Conclusion
If possible use the map or set objects available since ECMAScript 2015 to avoid this issue completly. If you need to emulated maps or sets in JavaScript ensure that the check of the existence of a key is done by using the method hasOwnProperty.

Dirk

Advertisements