函数是javascript对象属性的有效键吗?

Mar*_*une 13 javascript

我想在javascript对象中使用函数作为键.以下工作,至少在Chrome中:

var registry = {};
function Foo(){  };
function Bar(){  };
registry[Foo] = 42;
registry[Bar] = 43;
alert(registry[Foo] + " < " + registry[Bar]);
Run Code Online (Sandbox Code Playgroud)

这是否符合标准?它支持哪些浏览器?

Max*_*Art 15

你放在方括号之间的所有东西都被转换成一个字符串,即使你放了一个函数,一个日期,一个正则表达式就会发生这种情况......所以,你实际上是在创建一个像这样的对象:

var registry = {
    "function Foo(){  }" : 42,
    "function Bar(){  }" : 43
};
Run Code Online (Sandbox Code Playgroud)

这是一个默认行为,如果你想知道它也适用于IE.实际上,John Resig在他的着名addEvent职能中利用了它.

  • 请注意,具有不同闭包的函数可以转换为相同的字符串,并访问相同的属性.从节点控制台:> var maker = function(a){return function(){console.log(a); }; }; > var bb = maker('bb')> bb()bb> var cc = maker('dd')> cc()dd> var test = {}; > test [bb] ='AA''AA'> test [bb]'AA'> bb()bb> test {'function(){console.log(a); }':'AA'}> test [cc] ='DD''DD'> test {'function(){console.log(a); }':'DD'}>测试[bb]'DD'>测试[cc]'DD' (2认同)

Thi*_*ter 7

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. 如果正在评估的语法生成包含在严格模式代码中,则let strict为true,否则let strict为false.
  8. 返回类型为Reference的值,其基值为基值,其引用名称为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
})
Run Code Online (Sandbox Code Playgroud)