6502
6502

Reputation: 114569

What is the technical reason to forbid primitive types as key in a WeakMap?

The standard says so and there is no doubt that primitive types cannot be used as key in a WeakMap; but what is the technical reason for adding such a limitation?

I wanted to implement a simple hash function mapping JS values to 0-65535 and that would have been trivial by using a WeakMap; unfortunately I need to hash anything (including symbols and strings) but this is forbidden and I wonder why.

Upvotes: 5

Views: 850

Answers (2)

zch
zch

Reputation: 15278

Consider hypothetical function:

f = (i) => WeakMap([[i,2]]);

We would expect that once i is no longer referenced outside this map it will be removed from it. However, if I have code that invokes f(3453453) then value of 3453453 will be presumably indefinitely referenced by the interpreter and, as such, never removed from the returned map. In contrast, every time you execute code with object literal {} you get a new object, so you can trace if it will referencable or not.

I also expect JavaScript implementations to have many dedicated optimizations for primitive types, that could be impossible to keep compatible with checking if they are referenced or not. For example, you might be able to operate on value of 123 without having a dedicated memory location and object for it.

Upvotes: 0

Andrey Kostenko
Andrey Kostenko

Reputation: 382

WeakMaps are designed to map one weak-referenced object to another. Primitive types such as String, Number and so on are strong-referenced and designed in a way that when you assign a String value to a variable it doesn't assign a reference to the source string, but copies that value to the new variable (and therefore, e.g. when you change source variable, the new one won't change).

Weakly-referenced objects are made to be garbage-collected. When it's not used by any parts of the script, it will be removed and memory will be freed. Primitive types in JS are strong-referenced (values are copied, not referenced), therefore garbage collector will never trigger the deletion of that values, and deletion of that strongly-referenced, primitive typed keys in a map (which conflicts with the whole idea of WeakMap).

But if you still need to use primitive values as keys to WeakMap, you can try some workaround like wrapping primitive value in some object and then using that object as a key.

Upvotes: -1

Related Questions