2009-07-20 7 views
22

Ho appena ricevuto il seguente errore in un pezzo di javascript (in Firefox 3.5, con Firebug corsa)Javascript + Firebug: "impossibile accedere alla chiusura ottimizzata" Che cosa significa?

cannot access optimized closure 

Lo so, superficialmente, la causa dell'errore. Ho avuto una linea

options.length() 

invece di

options.length 

fissaggio questo bug, ha fatto il messaggio di andare via. Ma sono curioso Cosa significa questo? Cos'è una chiusura ottimizzata? Sta ottimizzando un recinto qualcosa che l'interprete javascript fa automaticamente? Che cosa fa?

+1

Che cosa sono le "opzioni"? un array? – rodrigoap

+2

Discussioni correlate su 'mozilla.dev.platform' di cinque giorni fa (07/15): http://groups.google.com/group/mozilla.dev.platform/browse_thread/thread/1f963989e7af0900 - Sfortunatamente, non fornisce gran parte di una risposta, sono semplicemente cross-linking – Tomalak

risposta

1

Una chiusura è una funzione con il contesto. Se crei dinamicamente una nuova funzione, crei una chiusura.

function makeAdder(int num) { 
    return function(int num2) { return num + num2; } 
} 

adder = makeAdder(5); 
adder(7) // returns (5+7) = 12 
adder(2) // returns (5+2) = 7 

Qui, la chiusura è la funzione interna, restituita da makeAdder, insieme al "5" passato.

Il motore javascript potrebbe scegliere di ottimizzare la funzione mostrata sopra, per far funzionare le cose più velocemente, senza generare o eseguire quel codice, quindi non può essere debugato o referenziato. Gli ottimizzatori dovrebbero fare molta attenzione per garantire che non ci sia alcun impatto, quindi immagino che questo abbia fatto un errore.

+1

Probabilmente intendevi: 'return function() {...}', non 'return new function() {...}' (dato che quest'ultimo istanzia realmente un nuovo oggetto usando la funzione come costruttore). Inoltre, non è necessario creare una funzione "dinamicamente" per creare una chiusura; qualsiasi espressione di funzione o dichiarazione di funzione si chiude su variabili libere nella sua catena di scope (tranne le funzioni create tramite 'Function', che sono impostate per contenere solo scope globali nella loro catena di scope). – kangax

4

Ho riscontrato questo problema anche quando Firebug è in esecuzione.

Sembra che capita a volte, quando viene sollevata un'eccezione (per qualsiasi motivo) e quando c'è una funzione ricorsiva chiama da qualche parte nello stack di chiamate. L'eccezione viene sollevata come il misterioso "InternalError: impossibile accedere alla chiusura ottimizzata"

Cambiando il modo in cui definisco la funzione ricorsiva, sembra che questo problema scompaia. ad esempio, si passa da

function foo(bar) {... foo(recursively); ...} 

a

var foo = function(bar) {... foo(recursively); ...} 

Speranza che aiuta.

+1

Ho avuto questo problema con una funzione ricorsiva, e questo ha risolto il problema per me! Grazie! – Skilldrick

+2

Cheers. Come è successo, è risultato che se la funzione è chiamata in modo ricorsivo o meno, non fa la differenza, lo stava solo dichiarando in questo modo annidato all'interno di un'altra funzione che ha causato il problema. –

+1

Questo lo ha risolto anche per me. Non era nemmeno una funzione ricorsiva. –

0

Ho riscontrato lo stesso errore oggi. Nel mio caso ciò si è verificato perché mi riferivo a un attributo o funzione di un oggetto che non esisteva o che non era disponibile. Suppongo che, poiché l'oggetto era disponibile tramite una chiusura ottimizzata, Firebug non poteva accedere ai metadati su quell'oggetto e quindi al messaggio di errore criptico.

3

Si tratta di un bug in Firefox accadendo con Firebug aperta:

https://bugzilla.mozilla.org/show_bug.cgi?id=505001

[Una risposta citato in precedenza questo era dovuto this other bug, che credo sia corretta come quell'altro problema non era legato a Firebug. ]

+0

I commenti su questo bug sembrano indicare che questo problema è stato risolto in Firefox 3.6. Sìì! Se qualcuno lo vede su 3.6, si prega di farlo presente in un newsgroup firebug. – Nickolay

0

Questo è successo anche a me oggi.Firebug error'd alla linea 2 di questa funzione:

 
function IsValidDate(objName) { 
    re = new RegExp('^(+|today|pdate|- *\\d+ *(day(s|)|week(s|))+ *$', 'i'); 
    if (re.test(objName.value)) return 2; 
    return (chkdate(objName)); 
} 

Quando ho aggiunto "var" prima della dichiarazione di "re" nella riga 1, l'errore è andato via.

0

C'è un'eccezione viene sollevata da qualche altra parte nel codice all'interno della funzione che ha questo errore. Potrebbe essere semplice provare ad accedere a una variabile che non esiste.

Penso che abbiamo bisogno di ottenere un dev Firebug qui per rispondere perché non fornisce un errore più specifico su dove nella chiusura che ha sollevato l'eccezione per richiedere l'errore.

È stato incollato options.length(), ma non è quello che ha provocato l'errore. Ciò che ha causato l'errore è il fatto che il bug era all'interno di una chiusura.

function(){ 
    array.length() 
} 

che dà l'errore

1

Questo può anche essere causato da una semplice condizione di competizione. Stavo solo rifacendo un oggetto "startup" che fa alcune cose prima che il documento sia pronto. Non appena ho provato ad accedere a un secondo oggetto definito immediatamente sotto l'oggetto di avvio ho ricevuto questo errore.

Avevo l'impressione che l'esecuzione dello script fosse in attesa fino a quando non è stato compilato tutto il codice. Chiaramente non è il caso. In attesa che i documenti pronti a chiamare i metodi sul secondo oggetto risolvessero il problema. Inoltre, l'uso di questa bella funzione 'dump()' conferma che il secondo oggetto viene definito solo parzialmente quando si verifica l'errore: http://www.openjs.com/scripts/others/dump_function_php_print_r.php