The MDN document on the JavaScript Map Object provides useful information but seems to leave out a few important points. Perhaps they are obvious to most but it's not clear to me why it works the way it does and I would appreciate clarification please.
It appears that the keys, when not strings, are references to objects including function objects. And, apart from function objects, it appears that the values of objects are references to the objects also. Thus, in the code below, mapF.get(updateFunc).b = 25 updates the object held in the map, as opposed to the mapF.get() returning a copy of the object only.
But the same doesn't appear to hold for the case when the value is a function object, but appears to make a copy of the function, such that after the function funcInMap is updated, the mapF.get('funcInMap')(4) returns 8 instead of 12; and therefore appears to be holdiong a copy of the original definition of funcInMap.
Am I making a mistake or is this the way it works and the way it should be expected to work? Thank you.
var funcInMap = function (x) {
return x * 2;
};
function updateFunc() {
funcInMap = function (x) { return x * 3; };
}
var mapF = new Map();
mapF.set(updateFunc, {a: 5, b: 10});
mapF.set('funcInMap',funcInMap);
console.log("b pre map update: " + mapF.get(updateFunc).b); // 10
mapF.get(updateFunc).b = 25;
console.log("b post map update: " + mapF.get(updateFunc).b); // 25
console.log(mapF.get(updateFunc));
console.log("funcInMap pre update : " + mapF.get('funcInMap')(4)); // 8
updateFunc();
console.log("funcInMap post update : " + funcInMap(4)); // 12
console.log("mapF funcInMap post update : " + mapF.get('funcInMap')(4)); // 8
Added after receiving answer.
function updateFunc() { }
var mapF = new Map(),
obj = {a: 5, b: 10};
mapF.set(updateFunc, obj);
console.log("Original obj: " + Object.values(mapF.get(updateFunc)));
// Return 5, 10
obj = {a: 105, b: 110};
console.log("Updated obj: " + Object.values(mapF.get(updateFunc)));
// Return 5, 10
/*
I would've been stupid to expect the second group to return
105, 110; but that is what I was expecting when the objects
were functions.
*/
After changing some of my project code to use maps instead of regular objects it occurred to me that I was being a bit stupid again in setting a map key to have a value that is an object. It would make sense perhaps in some cases; but if the objective is to relate some data to a DOM element or function in manner that is similar to adding properties to them but will never clash in the future, wouldn't the point be to add a map to a map?
So, the code example above of mapF.set(updateFunc, {a: 5, b: 10}) should be mapF.set(updateFunc, new Map( [ ['a', 5], ['b', 10] ] ) ) and properties can be added(etc.) using mapF.get(updateFunc).set('c', 20).
However, the inner map cannot be used without use get twice. Thus, it would appear that an null object would be more easily coded anyway.
function myFunc() { };
var map_map = new Map([ [myFunc, new Map([ ['a',10], ['b',20]]) ] ] );
var obj = Object.create(null, {
a: { value: 10, enumerable: true },
b: { value: 20, enumerable: true }
});
var map_obj = new Map([[myFunc, obj]]);
console.log( map_map.get(myFunc).get('a') ); //=> 10
console.log( map_map.get(myFunc)['a'] ); //=> undefined
console.log( map_obj.get(myFunc).a); // => 10