Le document MDN sur le Objet Map JavaScript fournit des informations utiles mais semble omettre quelques points importants. Ils sont peut-être évidents pour la plupart des gens, mais je ne comprends pas pourquoi cela fonctionne de cette façon et j'apprécierais une clarification.
Il apparaît que les clés, lorsqu'elles ne sont pas des chaînes de caractères, sont des références à des objets, y compris des objets fonctionnels. Et, en dehors des objets fonctions, il apparaît que les valeurs des objets sont des références aux objets également. Ainsi, dans le code ci-dessous, mapF.get(updateFunc).b = 25
met à jour l'objet contenu dans la carte, par opposition à l'objet mapF.get()
renvoyant uniquement une copie de l'objet.
Mais cela ne semble pas être le cas lorsque la valeur est un objet fonction, mais semble faire une copie de la fonction, de sorte qu'après la fonction funcInMap
est mis à jour, le mapF.get('funcInMap')(4)
renvoie à 8
au lieu de 12
; et semble donc détenir une copie de la définition originale de la funcInMap
.
Est-ce que je fais une erreur ou est-ce que c'est ainsi que cela fonctionne et que l'on doit s'attendre à ce que cela fonctionne ? Merci.
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
Ajouté après avoir reçu la réponse.
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.
*/
Après avoir modifié une partie du code de mon projet afin d'utiliser des cartes au lieu d'objets ordinaires, je me suis rendu compte que j'étais à nouveau un peu stupide en définissant un fichier de type map
key
d'avoir un value
qui est un object
. Cela aurait peut-être du sens dans certains cas ; mais si l'objectif est de relier certaines données à un élément ou à une fonction DOM d'une manière similaire à l'ajout de propriétés à ces derniers, mais qui ne s'entrechoqueront jamais à l'avenir, ne serait-il pas préférable d'ajouter une balise map
à un map
?
Ainsi, l'exemple de code ci-dessus de mapF.set(updateFunc, {a: 5, b: 10})
devrait être mapF.set(updateFunc, new Map( [ ['a', 5], ['b', 10] ] ) )
et les propriétés peuvent être ajoutées (etc.) à l'aide de la fonction mapF.get(updateFunc).set('c', 20)
.
Cependant, l'intérieur map
ne peut être utilisé sans utilisation get
deux fois. Ainsi, il semblerait qu'un null object
serait de toute façon plus facile à coder.
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