Являются ли функции действительными ключами для свойств объекта javascript?
Я хотел бы использовать функции как ключи в объекте javascript. Следующие работы, по крайней мере, в Chrome:
var registry = {};
function Foo(){ };
function Bar(){ };
registry[Foo] = 42;
registry[Bar] = 43;
alert(registry[Foo] + " < " + registry[Bar]);
Это покрывается стандартом? По каким браузерам он поддерживается?
Ответы
Ответ 1
Все, что вы помещаете между квадратными скобками, преобразуется в строку, и это происходит, даже если вы добавляете функцию, дату, регулярное выражение... Итак, вы на самом деле создаете такой объект:
var registry = {
"function Foo(){ }" : 42,
"function Bar(){ }" : 43
};
Это поведение по умолчанию, оно работает и в IE, если вам интересно. Фактически он был использован Джоном Ресигом в известной функции addEvent
.
Ответ 2
ECMAScript 5.1 - Раздел 11.2.1:
Произведение MemberExpression : MemberExpression [ Expression ]
оценивается следующим образом:
- Пусть baseReference будет результатом оценки MemberExpression.
- Пусть baseValue будет GetValue (baseReference).
- Пусть свойствоNameReference является результатом вычисления выражения.
- Пусть свойствоNameValue будет GetValue (propertyNameReference).
- Вызов CheckObjectCoercible (baseValue).
- Пусть свойствоNameString - ToString (propertyNameValue).
- Если синтаксическое производство, которое оценивается, содержится в коде строгого режима, пусть строгое истинно, иначе пусть строго быть ложным.
- Возвращает значение типа 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
})