2012-06-01 13 views
11

Mi piacerebbe utilizzare le funzioni come chiavi in ​​un oggetto javascript. I seguenti lavori, almeno in Chrome:Le funzioni sono chiavi valide per le proprietà dell'oggetto javascript?

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

È coperto dallo standard? Con quale browser è supportato?

+0

Beh, ha funzionato in Chrome. Quindi potrebbe funzionare in Safari e Firefox –

+0

penso che sia come avvisare una funzione, in qualche modo il motore la analizza come una stringa perché è permissiva ... Ma direi che non è una buona idea, a meno che non la lanci come stringa prima (è possibile che ciò mi chieda) – Sebas

+0

Le chiavi di qualsiasi tipo di qualsiasi oggetto del dizionario devono avere un'operazione == ben definita. Tale operazione non può essere definita per le funzioni (http://en.wikipedia.org/wiki/Rice%27s_theorem). –

risposta

14

Tutto ciò che si mette tra parentesi quadre viene convertito in una stringa, e questo accade anche se si mette una funzione, una data, un espressione regolare ... Quindi c'è, si sta effettivamente creando un oggetto come questo:

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

Questo è un comportamento predefinito, funziona anche in IE se vi stavate chiedendo. E 'stato effettivamente sfruttato da John Resig nel suo famous addEvent function.

+2

Si noti che le funzioni con chiusure diverse possono essere convertite nella stessa stringa e accedere alla stessa proprietà. Dalla console del nodo: > var maker = function (a) {return function() {console.log (a); }; }; > var bb = macchina ('bb') > bb() bb > var cc = macchina ('dd') > cc() dd > var test = {}; > prova [bb] 'AA' = 'AA' > prova [bb] 'AA' > bb() bb > prova { 'function() {console.log (a); } ':' AA '} > test [cc] =' DD ' ' DD ' > test {' function() {console.log (a); } ':' DD '} > test [bb] ' DD ' > test [cc] ' DD ' – JoeAndrieu

4

ECMAScript 5.1 - Sezione 11.2.1:

La produzione MemberExpression : MemberExpression [ Expression ] è valutata come segue:

  1. Let baseReference essere il risultato della valutazione MemberExpression.
  2. Lasciare baseValue essere GetValue (baseReference).
  3. Lascia che propertyNameReference sia il risultato della valutazione di Expression.
  4. Lascia che propertyNameValue sia GetValue (propertyNameReference).
  5. Chiama CheckObjectCoercible (baseValue).
  6. Lasciare che PropertyNameString sia ToString (propertyNameValue).
  7. Se la produzione sintattica che viene valutata è contenuta in un codice di modalità rigoroso, è necessario che sia strict, altrimenti lasciare strict false.
  8. Restituisce un valore di tipo Riferimento il cui valore di base è Base value e il cui nome di riferimento è propertyNameString e il cui flag di modalità strict è rigoroso.

Così quando si utilizza obj[whatever], whatever viene convertito in una stringa. Per una funzione questa sarà una stringa contenente il codice sorgente della funzione.

Esempio:

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 
}) 
Problemi correlati