2012-04-25 14 views
15

El operador delete elimina una propiedad de un objeto. Si fijo una propiedad en window, puedo borrarlo:¿Por qué puede eliminar una propiedad anulada de la ventana?

window.myProp = 10; 
delete window.myProp; 

Como the article que tan a menudo referir a otros a lo que se refiere al comportamiento de los delete estados del operador, esto se debe a asignación de propiedad no establece el DontDelete atributo (a diferencia de la declaración de variables, que sí lo hace).

Ese artículo también afirma lo siguiente (énfasis añadido):

en cuenta que es durante la creación de la propiedad que se atribuye determinada (es decir, ninguno de ellos está configurado). Las asignaciones posteriores no modifican los atributos de la propiedad existente. Es importante entender esta distinción .

Teniendo esto en mente, ¿por qué puedo anular una propiedad existente de la ventana, alert, y luego eliminarlo para retorno al valor original? ¿Me estoy perdiendo algo obvio? Raramente utilizo el operador delete, así que ese puede ser el caso.

Por ejemplo:

window.alert = function() {}; 
alert("Hi!"); //Nothing happens 

delete window.alert; 
alert("Hello?"); //Alerts 'Hello?' 

Aquí hay una fiddle para demostrar que (sólo probado en Chome, bastante seguro de IE no comportarse de esta manera, pero no tienen acceso a nada, pero Chrome en este momento).

+0

'delete' en objetos host no se puede confiar y no funciona en IE. – Esailija

+0

posible duplicado de [alerta() no funciona en Chrome] (http://stackoverflow.com/questions/6184169/alert-not-working-in-chrome) –

+0

No lo sé pero me gusta su pregunta. Supongo que es algo así como un estilo CSS en un elemento que anula su estilo heredado, y si ese estilo de elemento se elimina a través de JS, vuelve al estilo heredado ... solo puede anularlo, nunca se elimina, solo teoría. Además, ¿qué pasaría si intentas eliminar window.alert sin haberlo definido primero como algo diferente? – squarephoenix

Respuesta

9

En Chrome, la función window.alert es parte de la prototipo de la clase DOMWindow, no es una propiedad de window sí.

De ahí que cuando se sobrescribe window.alert va a añadir una propiedad nueva a window, pero la versión en el prototipo continúa existiendo, pero está oculto.

Cuando delete window.alert la función en el prototipo se vuelve a exponer.

aquí hay algo de salida de la consola que muestra que la función está en el prototipo:

> window.constructor.prototype 
DOMWindow 

> window.constructor.prototype.alert 
function alert() { [native code] } 

Firefox comporta de manera similar, aunque con diferentes nombres de clase.

+0

Ahhh ¡Sabía que iba a ser algo obvio que estaba pasando por alto! Gracias. –

+0

@Alnitak Gran respuesta .. @ James también podemos eliminar la propiedad de alerta en el objeto prototipo, pero me opondría estrictamente a hacer eso ... No deberíamos modificar los objetos que no poseemos ... Así que, idealmente, no deberíamos eliminar la propiedad de alerta de ventana también – sachinjain024

+0

Gracias por esto. Tenemos alguna incompetencia de la que ocuparnos: solo podemos agregar nuestro código al sitio del cliente en un elemento particular, no podemos tocar las secuencias de comandos antes en la página o poner ningún código antes de que se ejecuten. Y anteriormente en la página se ejecutó una secuencia de comandos que vacia cadenas de idioma en el espacio de nombres global, incluyendo 'abrir =" Abrir ";'. De repente, el SDK de Facebook no puede abrir diálogos en dispositivos móviles. Tu respuesta nos ayudó a rescatar a window.open. – tremby

2

Este es el comportamiento previsto, se denomina sombreado. Le permite proporcionar una funcionalidad personalizada sin borrar la funcionalidad de las súper clases. Cuando elimina el método, su método personalizado se elimina, revelando el método original del prototipo.

Cuanto más profundice en la herencia y comprenda la forma en que funciona el prototipo, más se encontrará viendo instancias de personas haciendo esto.

Excelente pregunta. Este no es un área que la mayoría de los desarrolladores de JavaScript exploren con frecuencia en mi experiencia. Si no fuera por este tipo de cosas, muchos polyfills que extienden o anulan la funcionalidad central de los objetos base de JavaScript no serían posibles.

Cuestiones relacionadas