2009-07-02 7 views
60

Non riesco a trovare alcuna informazione su questo problema; perché il seguente codice non funziona in IE?Eliminazione di una proprietà della finestra in IE

window.x = 45; 
delete window.x; 
// or delete window['x']; 

IE segnala un errore "l'oggetto non supporta questa azione". Ha qualcosa a che fare con l'iterazione delle proprietà della finestra nel problema di IE?

+25

E tanto per essere chiari, perché non sembra che nessuno abbia detto questo in nessuna delle risposte: questo è un * bug * in Internet Explorer. Non c'è nulla nella specifica del 1999 (3a edizione) che consente di lanciare un'eccezione da 'delete', anche se la proprietà è inesistente o non cancellabile (che il tuo' window.x' non dovrebbe essere in ogni caso), e la nuova quinta edizione specifica consente solo eccezioni generate da 'elimina' nella nuova modalità rigorosa. Non c'è niente di speciale in 'window' in questo senso. Eppure, il motore JScript in IE8 * ancora * mostra questo bug, nel 2010. * sigh * –

+2

[Buon articolo pertinente] (http://perfectionkills.com/understanding-delete/). – alex

+0

T.J. Crowder, la finestra non è un oggetto, è un accessorio del namespace di root. Non ha proprietà in quanto tali, quindi quando si esegue l'eliminazione su di esso, come in questo caso, non è obbligato a rimuoverle effettivamente per qualsiasi motivo. L'impostazione indefinita sul nome dell'oggetto va bene perché il gc attraverserà ed eliminerà gli oggetti non referenziati. Spero che questo aiuti a capire il vero problema qui e perché questo non è tanto un bug in quanto è una scelta di implementazione scarsa per il linguaggio che si sta lentamente aggiornando per modernizzare –

risposta

31

vorrei fare in questo modo:

window[x] = undefined; 
    try{ 
     delete window[x]; 
    }catch(e){} 
+0

grazie, è quello che ho fatto alla fine. Genera un'eccezione in IE, ma viene catturato e nessun danno è fatto. –

+0

La spiegazione più approfondita dell'eliminazione che ho visto è qui, questa è la sezione IE. (Nel caso qualcuno arrivasse a questo con un problema più complicato in futuro) http://perfectionkills.com/understanding-delete/#ie_bugs –

2

Questo aiuto?

Ho provato questo in IE e window.x ha avuto un valore, che dimostra che può essere impostato. Impostare il valore su null è la soluzione migliore per eliminarlo.

+0

Sfortunatamente questo non rimuove la variabile dalla memoria, semplicemente lo dà un valore nullo, ma questa è l'unica opzione per quanto posso dire. –

+1

Grazie. Ho fatto un ulteriore passo avanti e ho usato window.x = indefinito. Questo non è ancora quello che voglio, ma lo farà.È strano che non abbia trovato alcuna informazione utile sul web su questo. –

48

Gasper ha fatto un commento con la soluzione ha finito, ma penso che ne vale la pena gridando come una risposta reale:

try 
{ 
    delete window.x; 
} 
catch(e) 
{ 
    window["x"] = undefined; 
} 

questione interessante Stavo solo sbattendo la testa contro di esso stasera. L'eccezione è lanciata su IE ma non su Firefox. Sospetto che questa soluzione rimanga in memoria, quindi usala con parsimonia.

È stato chiesto, perché non assegnare solo undefined? È importante se si desidera enumerare le chiavi in ​​un secondo momento (anche se si sta facendo affidamento sulla soluzione alternativa, l'enumerazione delle chiavi non farà comunque ciò che si desidera ...). Ma tant'è, per evidenziare la differenza tra eliminazione e semplicemente assegnando indefinito (http://jsfiddle.net/fschwiet/T4akL/):

var deleted = { 
    a: 1 
}; 

var cleared = { 
    a: 1 
}; 

delete deleted["a"]; 
cleared["a"] = undefined; 

for(var key in deleted) { 
    console.log("deleted has key", key); 
} 

for(var key in cleared) { 
    console.log("cleared has key", key); 
} 

console.log("deleted has a?", deleted.hasOwnProperty('a')); 
console.log("cleared has a?", cleared.hasOwnProperty('a')); 

produce un output:

cleared has key a 
deleted has a? false 
cleared has a? true 
+4

Un collega ha chiesto una buona idea quando ho mostrato loro questa soluzione: perché non saltare l'uomo medio e sostituire la chiamata di eliminazione con l'assegnazione indefinita? –

+0

Buona domanda, mi ci è voluto un anno per imbattersi in un caso in cui la differenza è importante. –

1

ho implementato questa soluzione quando si tratta di caching mia dati - i dati wasn' t molto la frequenza della cache era tale che la perdita di memoria poteva essere diventata un problema. È costoso, ma rimappare periodicamente l'oggetto è stato il modo più semplice per me per essere sicuro che non sfuggisse di mano.

obj = {a: 1, b: 2, c: 3}; 
var max; 

function unset(obj, key) { 
    try { 
     delete obj[key]; 
    } catch (e) { 
     obj[key] = undefined; 
    } 

    max++; 

    if(max > 200) { 
     var keys = Object.keys(obj); 
     var len = keys.length; 
     var n_obj = {}; 
     for(var i = 0; i < len; i++) { 
      if(obj.hasOwnProperty(keys[i]) && obj[keys[i]] !== undefined) { 
       n_obj[keys[i]] = obj[keys[i]]; 
      } 
     } 
     return n_obj; 
    } 
    return obj; 
} 

obj; //{a: 1, b: 2, c: 3} 
obj = unset(obj, "b"); //{a: 1, b: undefined, c: 3} OR {a: 1, c: 3} 
//and then eventually we'll garbage collect and... 
obj = unset(obj, "b"); //{a: 1, c: 3} 

Speriamo che sia utile per alcuni!

+2

'Object.keys()' non funzionerà in <= IE8 (che sono quelli che causano problemi con 'delete' in primo luogo). Inoltre, probabilmente intendevi "obj [chiave] = indefinito" all'interno del blocco catch. ;] – WynandB

+0

quello sarebbe! rivisto. – Mikebert4

Problemi correlati