Reputation: 2692
Consider two different function objects created by the same expression or declaration (i.e. by the same line of code). In this example (which you can run), those functions are wa
and wb
, created by the same expression in the wrap
function:
function a() { return "abc" }
function b() { return 123 }
function wrap(f) { return () => f() }
var wa = wrap(a)
var wb = wrap(b)
Any such two functions
===
,Object.is
,Map
.Key equality is based on the
sameValueZero
algorithm:NaN
is considered the same asNaN
(even thoughNaN !== NaN
) and all other values are considered equal according to the semantics of the===
operator.
You can read their definitions of same-value-zero and same-value as well. By my reading, two different function objects should be two different keys.
(Object
s exhibit the same behavior, but because they aren't meant to support keys that aren't strings or symbols, I am giving them a pass. I am tagging them because there is no tag for Map
s.)
Upvotes: 0
Views: 517
Reputation: 371019
You're not setting the Map key correctly - you're treating the Map as an ordinary object, and putting keys on an ordinary object results in the keys being cast to strings. So
var m = new Map()
m[wa] = "hello, world!"
m[wb]
coerces the wa
and wb
to strings (because object keys may only be strings), and the above code resolves to
var m = new Map()
m["() => f()"] = "hello, world!"
m["() => f()"]
To use the Map properly (so that it can have keys of any type, including functions and objects, that don't get coerced to strings), use Map.set
and Map.get
instead. Then, the behavior will be as expected - the two separate functions, not being ===
to each other, will have different keys in the Map:
function a() { return "abc" }
function b() { return 123 }
function wrap(f) { return () => f() }
var wa = wrap(a)
var wb = wrap(b)
const m = new Map();
m.set(wa, 'Hello World');
console.log(m.get(wb)); // undefined; the map sees wa and wb as different, as expected
Upvotes: 2