为什么我不能使用函数作为Map的键?

时间:2019-08-14 01:10:05

标签: javascript javascript-objects

考虑由同一表达式或声明(即同一行代码)创建的两个不同的函数对象。在此example (which you can run)中,这些函数是wawb,它们是由wrap函数中的相同表达式创建的:

function a() { return "abc" }
function b() { return 123 }
function wrap(f) { return () => f() }
var wa = wrap(a)
var wb = wrap(b)

这两个功能

  • 根据===的比较结果不相等,
  • 根据Object.is的比较结果不相等,
  • ,但Map将其视为等号。

MDN says

  

密钥相等性基于sameValueZero算法:NaN被认为与NaN相同(即使NaN !== NaN),并且根据===运算符的语义。

您也可以阅读它们对same-value-zerosame-value的定义。根据我的阅读,两个不同的功能对象应该是两个不同的键。

({Object s表现出相同的行为,但是由于它们不支持非字符串或符号的键,因此我给了它们一个通行证。我对其进行了标记,因为没有用于Map。)

1 个答案:

答案 0 :(得分:2)

您没有正确设置Map键-您将Map视为普通对象,将键放在普通对象上会导致键转换为字符串。所以

var m = new Map()
m[wa] = "hello, world!"
m[wb]

wawb强制转换为字符串(因为对象键只能是字符串),并且上述代码解析为

var m = new Map()
m["() => f()"] = "hello, world!"
m["() => f()"]

要正确使用Map(以便它可以具有任何类型的键,包括不强制转换为字符串的函数和对象),请使用Map.set和{{ 1}}。然后,行为将如预期的那样-彼此不Map.get的两个单独的函数在Map中将具有不同的键:

===