It may not be common knowledge, but "Javascript on many (all?) modern browsers seems to create variables on the window object for DOM elements with IDs".
Knowing this I'd like to be able to delete these variables and below is some code I've tried without success. Also consider my screenshot of console.log statements, which first indicates why
as not being a property of window (it should come in between "webkitUrl" and "window"), but nevertheless in the two console.log statements that immediately follow the first, window/why is shown as the div from the document?
Why can't these automatically generated variables be deleted from their parent object, just like any other?
<!DOCTYPE html>
<html>
<head>
<script>
setTimeout(function() { //poor man's document/ready
var allElements = document.getElementsByTagName("*"), elementId;
for (var i=allElements.length; i--; ) {
elementId = allElements[i].id;
if (elementId && window[elementId] instanceof HTMLElement) {
delete window.why;
console.log(window);
console.log(window.why);
console.log(why);
}
}
});
</script>
</head>
<body>
<div id="why"></div>
</body>
</html>
That's because these properties are not directly stored in window
. Instead, it behaves like a proxy.
For example, see what Firefox does when you use getOwnPropertyDescriptor
on WindowProperties
(from which window
inherits):
bool WindowNamedPropertiesHandler::getOwnPropDescriptor(
JSContext* aCx, JS::Handle<JSObject*> aProxy, JS::Handle<jsid> aId,
bool /* unused */, JS::MutableHandle<JS::PropertyDescriptor> aDesc
) const {
// ...
Element* element = document->GetElementById(str);
if (element) {
JS::Rooted<JS::Value> v(aCx);
if (!WrapObject(aCx, element, &v)) {
return false;
}
FillPropertyDescriptor(aDesc, aProxy, 0, v);
return true;
}
// ...
}
You might think that when you set an ID to some element, Firefox stores it as a global property. But it doesn't work like this: it's when you attempt to access the property that Firefox will use GetElementById
to know if there is some element with that ID or not, and answer accordingly.
Even more, deletions are explicitly forbidden:
bool WindowNamedPropertiesHandler::delete_(
JSContext* aCx, JS::Handle<JSObject*> aProxy,
JS::Handle<jsid> aId, JS::ObjectOpResult &aResult
) const {
return aResult.failCantDeleteWindowNamedProperty();
}
This behavior is hard-coded and you can't prevent it. So if these properties annoy you, just override them by declaring your own variables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With