16

我想将函数用作 javascript 对象中的键。以下工作,至少在 Chrome 中:

var registry = {};
function Foo(){  };
function Bar(){  };
registry[Foo] = 42;
registry[Bar] = 43;
alert(registry[Foo] + " < " + registry[Bar]);

这是否包含在标准中?支持哪些浏览器?

4

2 回答 2

17

您放在方括号之间的所有内容都会转换为字符串,即使您放置了一个函数、一个日期、一个正则表达式,也会发生这种情况......所以,您实际上是在创建一个像这样的对象:

var registry = {
    "function Foo(){  }" : 42,
    "function Bar(){  }" : 43
};

这是默认行为,如果您想知道,它也适用于 IE。它实际上被 John Resig 在他著名的addEvent功能中利用了。

于 2012-06-01T23:51:47.657 回答
8

ECMAScript 5.1 - 第 11.2.1 节:

生产MemberExpression : MemberExpression [ Expression ]评估如下:

  1. 让 baseReference 成为评估 MemberExpression 的结果。
  2. 让 baseValue 为 GetValue(baseReference)。
  3. 让propertyNameReference 成为计算Expression 的结果。
  4. 让 propertyNameValue 为 GetValue(propertyNameReference)。
  5. 调用 CheckObjectCoercible(baseValue)。
  6. 让 propertyNameString 为 ToString(propertyNameValue)。
  7. 如果正在评估的语法产生包含在严格模式代码中,则让 strict 为真,否则让 strict 为假。
  8. 返回一个 Reference 类型的值,其基值为 base Value ,其引用名称为 propertyNameString ,其严格模式标志为 strict。

所以在使用时obj[whatever]whatever会转换为字符串。对于函数,这将是一个包含函数源代码的字符串。

例子:

js> var func = function() { return 'hi'; };
js> function helloworld() { return 'hello world'; }
js> var obj = {};
js> obj[func] = 123;
js> obj[helloworld] = 456;
js> obj
({'function () {\n    return "hi";\n}':123,
  'function helloworld() {\n    return "hello world";\n}':456
})
于 2012-06-02T00:02:28.310 回答