2012-06-01 4 views
11

Я хотел бы использовать функции как ключи в объекте javascript. Следующие работы, по крайней мере в Хром:Являются ли функции действительными ключами для свойств объекта javascript?

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

Это покрывается стандартом? По каким браузерам он поддерживается?

+0

Ну, работал в Chrome. Так что это может сработать в Safari и Firefox –

+0

Я думаю, что это похоже на то, что вы предупреждаете о функции, так как двигатель анализирует ее как строку, потому что она разрешима ... Но я сказал, что это не очень хорошая идея, как строка сама до этого (возможно, так мне интересно) – Sebas

+0

Ключи любого типа объекта словарного класса должны иметь четко определенную операцию. Такая операция не может быть определена для функций (http://en.wikipedia.org/wiki/Rice%27s_theorem). –

ответ

14

Все, что вы в квадратных скобках, преобразуется в строку, и это происходит, даже если вы поставите функцию, дату, регулярное выражение ... Так что, вы фактически создаете объект вроде этого:

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

Это поведение по умолчанию, оно работает и в IE, если вам интересно. Фактически он был использован Джоном Ресигом в его famous addEvent function.

+2

Обратите внимание, что функции с разными замыканиями могут быть преобразованы в одну и ту же строку и получить доступ к тому же свойству. С консоли узла: > var maker = function (a) {return function() {console.log (a); }; }; > вар бб = мейкера ('BB') > бб() бб > вар куб.см = мейкера ('дд') > куб.см() дд > Тест переменная = {}; > тест [бб] 'AA' = 'АА' > тест [бб] 'АА' > бб() бб > Тест { «функция() {console.log (а); } ':' AA '} > test [cc] =' DD ' ' DD ' > test {' function() {console.log (a); } ':' DD '} > test [bb] ' DD ' > test [cc] ' DD ' – JoeAndrieu

4

ECMAScript 5.1 - Раздел 11.2.1:

Производство MemberExpression : MemberExpression [ Expression ] оценивается следующим образом:

  1. Пусть baseReference быть результатом оценки MemberExpression.
  2. Пусть baseValue будет GetValue (baseReference).
  3. Позволить propertyNameReference быть результатом оценки выражения.
  4. Пусть свойствоNameValue будет GetValue (propertyNameReference).
  5. Call CheckObjectCoercible (baseValue).
  6. Пусть свойствоNameString будет ToString (propertyNameValue).
  7. Если синтаксическое производство, которое оценивается, содержится в коде строгого режима, пусть строгое истинно, иначе пусть строго будет ложным.
  8. Возвращает значение типа Reference, базовое значение которого является базовым значением, а ссылочным именем является propertyNameString и строгий флаг строгого режима.

Так при использовании 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 
}) 
Смежные вопросы