2009-07-02 18 views
60

No encuentro ninguna información sobre este problema; ¿Por qué el siguiente código no funciona en IE?Eliminando una propiedad de ventana en IE

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

IE informa un error "el objeto no admite esta acción". ¿Tiene algo que ver con esa iteración sobre las propiedades de la ventana en el problema de IE?

+25

Y para que quede claro, porque no parece que nadie haya dicho esto en ninguna de las respuestas: Este es un * error * en Internet Explorer. No hay nada en la especificación de 1999 (3ª edición) que permita lanzar una excepción desde 'eliminar', incluso si la propiedad no es inexistente o no recuperable (que su' window.x' no debería ser en cualquier caso), y el La nueva especificación de quinta edición solo permite excepciones lanzadas desde 'delete' en el nuevo modo estricto. No hay nada especial acerca de 'window' en este sentido. Y, sin embargo, el motor de JScript en IE8 * aún * exhibe este error, en 2010. * suspiro * –

+2

[Artículo relevante]] (http://perfectionkills.com/understanding-delete/). – alex

+0

T.J. Crowder, la ventana no es un objeto, es un acceso al espacio de nombres raíz. No tiene propiedades como tales, por lo que cuando ejecuta eliminar en él, como en este caso, no está obligado a eliminarlos por ningún motivo. Definir indefinido en el nombre del objeto está bien porque el gc pasará y eliminará los objetos sin referencia. Espero que esto ayude a entender el problema real aquí y por qué esto no es tanto un error, ya que es una mala elección de implementación para el lenguaje que se está actualizando lentamente para modernizar –

Respuesta

31

lo haría de esta manera:

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

gracias, eso es lo que hice al final. Lanza una excepción en IE, pero se detecta y no se produce ningún daño. –

+0

La explicación más detallada de la eliminación que he visto está aquí, esta es la sección de IE. (En el caso de que alguien llegue a esto con un problema más complicado en el futuro) http://perfectionkills.com/understanding-delete/#ie_bugs –

2

¿Le sirve de ayuda?

window.x = 45; 
alert(window.x); 
window.x = null; 

yo probamos este en IE y window.x tenía un valor, lo que demuestra que se puede ajustar. Establecer el valor a nulo es su mejor opción para despejarlo.

+0

Desafortunadamente, esto no elimina la variable de la memoria, simplemente la da un valor nulo, pero esta es la única opción por lo que puedo decir. –

+1

Gracias. He ido un paso más allá y usé window.x = undefined. Esto todavía no es lo que quiero, pero servirá.Es extraño que no haya encontrado información útil en la web sobre esto. –

48

Gasper hizo un comentario con la solución que terminó, pero creo que es digna de ser llamada como una respuesta real:

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

tema interesante , Solo estaba golpeando mi cabeza contra esta noche. La excepción se produce en IE pero no en Firefox. Sospecho que esta solución filtra memoria, así que utilícela con moderación.

Se le preguntó, ¿por qué no simplemente asignar undefined? Importa si desea enumerar las claves más adelante (aunque si confía en la solución alternativa, la enumeración de claves aún no hará lo que quiera ...). Pero de todos modos, para poner de relieve la diferencia entre borrar y simplemente asignar indefinido (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 una salida:

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

Un colega me preguntó una buena pregunta cuando les mostré esta solución: ¿por qué no omitir al intermediario? y reemplazar la llamada de eliminación con la tarea indefinida? –

+0

Buena pregunta, me llevó un año encontrarme con un caso donde la diferencia importa. –

1

he implementado esta solución cuando se trata de almacenamiento en caché de mi propia de datos - los datos no estaba' Tanto la frecuencia de la memoria caché era tal que la pérdida de memoria podría haberse convertido en un problema. Es costoso, pero el remapeo periódico del objeto fue la forma más fácil para mí de estar seguro de que no estaba fuera de control.

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} 

Afortunadamente, eso es útil para algunos.

+2

'Object.keys()' no funcionará en <= IE8 (que son los que causan problemas con 'delete' en primer lugar). Además, probablemente significó 'obj [key] = undefined' dentro del bloque catch. ;] – WynandB

+0

eso sería! revisado. – Mikebert4

Cuestiones relacionadas