Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can you delete an overridden property of window?

Tags:

javascript

The delete operator removes a property from an object. If I set a property on window, I can delete it:

window.myProp = 10;
delete window.myProp;

As the article I so often refer others to when it comes to the behaviour of the delete operator states, this is because property assignment does not set the DontDelete attribute (as opposed to variable declaration, which does).

That article also states the following (emphasis added):

Note that it is during property creation that attributes are determined (i.e. none are set). Later assignments don’t modify attributes of existing property. It’s important to understand this distinction.

Bearing that in mind, why can I override an existing property of window, alert, and then delete it to return to the original value? Am I missing something obvious? I rarely use the delete operator so that may well be the case.

For example:

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

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

Here's a fiddle to demonstrate that (only tested in Chome, pretty sure IE will not behave this way but don't have access to anything but Chrome right now).

like image 275
James Allardice Avatar asked Apr 25 '12 16:04

James Allardice


2 Answers

In Chrome, the window.alert function is part of the prototype of the DOMWindow class, it's not a property of window itself.

Hence when you overwrite window.alert you're adding a new property to window, but the version in the prototype continues to exist, but is hidden.

When you delete window.alert the function in the prototype is re-exposed.

Here's some console output showing that the function is in the prototype:

> window.constructor.prototype
DOMWindow

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

Firefox behaves similarly, albeit with different class names.

like image 147
Alnitak Avatar answered Nov 20 '22 05:11

Alnitak


This is the intended behavior, it's called shadowing. It permits you to provide custom functionality without wiping out the functionality of super classes. When you delete the method, your custom method is deleted, revealing the original method from prototype.

The deeper you go into inheritance and understanding the way prototype works, the more you'll find yourself seeing instances of people doing this.

Excellent question. This is not an area often explored by most JavaScript developers in my experience. If it weren't for this type of thing, many polyfills which extend or override the core functionality of JavaScript base objects wouldn't be possible.

like image 36
Sampson Avatar answered Nov 20 '22 03:11

Sampson