JS Map Key Gotcha


Published: 2016-04-30
Updated: 2016-06-12
Web: http://fritzthecat-blog.blogspot.com/2016/04/js-map-key-gotcha.html


Another JavaScript gotcha:

Demo Source


An empty map (object) is created and assigned to variable map. Keys of different types are stored into that map, using the key also as value. The map is then iterated by a for-in loop, to receive both key and value inside the loop. Key and value types are written to the output, which finally is displayed.

Press "Run" to see that this yields:


typeof key = string, typeof(value) = object
typeof key = string, typeof(value) = function
typeof key = string, typeof(value) = number

JavaScript converts every map key to a string!

Background

You could also say that every object member is identified by a string, and nothing else but a string.

There is no difference between an object and a map in JS. For example, would you regard the following to be valid JavaScript code?


There is no difference between addressing the value via map["key"] or map.key. Thus you could also establish functions with spaces in their name on objects/maps, but you need to address them as map values then:


Consequences

Such becomes painful when you want to map things to integers, and you assume you can use these map keys as numbers then. Consider following real world example:


As you can see, the output is empty.

Now replace the

if (width === currentWidth)

in the searchWidth() function by

if (width == currentWidth)

and click "Run". Now it will work as expected. Reason is that JS performs a type conversion when encountering the "==" operator. It tries to bring both comparison values to the same type. It does not do this when using the "===" operator (identity comparison). The same applies to "!=" and "!==".
But that is not the way how we should fix this!

Mind that you always SHOULD use "===" for comparisons, this is the better programming style. It would prove that none of your variables changes its type on the fly. So the way to fix this is NOT replacing "===" by "==", but converting the string back to a number:


var intWidth = window.parseInt(width);
if (intWidth === currentWidth) {
....

What we learn:





ɔ⃝ Fritz Ritzberger, 2016-04-30