Ce que vous avez décrit est couvert par Harmony WeakMaps qui fait partie de la ECMAScript 6 (prochaine version de JavaScript). C'est-à-dire : un ensemble dont les clés peuvent être n'importe quoi (y compris indéfini) et qui n'est pas dénombrable.
Cela signifie qu'il est impossible d'obtenir une référence à une valeur sans avoir une référence directe à la clé (n'importe quel objet !) qui y est liée. C'est important pour un tas de raisons d'implémentation du moteur liées à l'efficacité et à la collecte des déchets, mais c'est aussi super cool car cela permet une nouvelle sémantique comme les permissions d'accès révocables et le passage de données sans exposer l'expéditeur des données.
De MDN :
var wm1 = new WeakMap(),
wm2 = new WeakMap();
var o1 = {},
o2 = function(){},
o3 = window;
wm1.set(o1, 37);
wm1.set(o2, "azerty");
wm2.set(o1, o2); // A value can be anything, including an object or a function.
wm2.set(o3, undefined);
wm2.set(wm1, wm2); // Keys and values can be any objects. Even WeakMaps!
wm1.get(o2); // "azerty"
wm2.get(o2); // Undefined, because there is no value for o2 on wm2.
wm2.get(o3); // Undefined, because that is the set value.
wm1.has(o2); // True
wm2.has(o2); // False
wm2.has(o3); // True (even if the value itself is 'undefined').
wm1.has(o1); // True
wm1.delete(o1);
wm1.has(o1); // False
Les WeakMaps sont disponibles dans les versions actuelles de Firefox, Chrome et Edge. Elles sont également prises en charge dans Node v7 , et dans la v6 avec l'option "WeakMaps". --harmony-weak-maps
drapeau.
34 votes
La raison pour laquelle les objets ont tous la même valeur est que vous n'avez pas surchargé leurs méthodes toString. Comme les clés doivent être des chaînes de caractères, la méthode toString est automatiquement appelée pour obtenir une clé valide, de sorte que tous vos objets sont convertis à la même chaîne de caractères par défaut : "[objet Object]".
5 votes
JSON.stringify(obj)
oobj.toSource()
peut vous convenir en fonction du problème et de la plate-forme cible.4 votes
@Annan JSON.stringify(obj) convertit littéralement l'objet (entier) en une chaîne de caractères. Vous ne feriez donc que copier l'objet sur lui-même. C'est inutile, un gaspillage d'espace et non optimal.
1 votes
@Metalstorm Vrai, c'est pourquoi cela dépend de votre problème. Lorsque j'ai trouvé cette question sur Google, ma solution finale était d'appeler toSource() sur les objets. Une autre méthode serait simplement d'utiliser un hachage conventionnel sur la source.
0 votes
@Annan,
toSource
ne fonctionnent pas dans Chrome0 votes
Eh bien, si tu utilises node.js, npmjs.com/package/object-hash