为什么无法删除从 DOM 自动生成的 Javascript 变量?
Why isn't it possible to delete Javascript variables automatically generated from the DOM?
这可能不是常识,但是"Javascript on many (all?) modern browsers seems to create variables on the window object for DOM elements with IDs"。
知道这一点后,我希望能够删除这些变量,下面是我尝试过但没有成功的一些代码。还要考虑我的 console.log 语句的屏幕截图,它首先表明 why
不是 window 的 属性(它应该介于 "webkitUrl" 和 "window"), 但在紧跟第一个语句之后的两个 console.log 语句中,window/why 显示为文档中的 div?
为什么这些自动生成的变量不能像其他任何变量一样从它们的父对象中删除?
<!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>
I'd like to be able to delete these variables
绝对没有理由这样做。这些全局变量 are there for backwards compatibility 和浏览器几乎不会删除它们。但是,它们的创建方式使您可以简单地忽略它们 - 它们不会干扰您的任何变量。
只需在您的脚本中声明 var why;
,对元素的引用就会消失。
Why can't these automatically generated variables be deleted from their parent object?
首先,变量一般是不能删除的。只有对象属性可以——只是有些全局变量是全局对象的可删除属性。
元素引用可能无法删除,因为 a) 它们不是真正的属性而是代理 b) 它们不是全局对象本身的属性,而是其原型的属性或 c) 它们是属性全局范围内的额外变量记录。就当他们是魔法,不在乎了。
那是因为这些属性没有直接存储在window
中。相反,它的行为就像一个代理。
例如,当您在 WindowProperties
上使用 getOwnPropertyDescriptor
(window
从中继承)时,请参阅 what Firefox does:
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;
}
// ...
}
您可能会认为,当您为某个元素设置 ID 时,Firefox 会将其存储为全局 属性。但它不是这样工作的:当您尝试访问 属性 时,Firefox 将使用 GetElementById
来了解是否存在具有该 ID 的元素,并做出相应的回答。
更重要的是,deletions 被明确禁止:
bool WindowNamedPropertiesHandler::delete_(
JSContext* aCx, JS::Handle<JSObject*> aProxy,
JS::Handle<jsid> aId, JS::ObjectOpResult &aResult
) const {
return aResult.failCantDeleteWindowNamedProperty();
}
此行为是硬编码的,您无法阻止它。因此,如果这些属性让您烦恼,只需通过声明您自己的变量来覆盖它们。
这可能不是常识,但是"Javascript on many (all?) modern browsers seems to create variables on the window object for DOM elements with IDs"。
知道这一点后,我希望能够删除这些变量,下面是我尝试过但没有成功的一些代码。还要考虑我的 console.log 语句的屏幕截图,它首先表明 why
不是 window 的 属性(它应该介于 "webkitUrl" 和 "window"), 但在紧跟第一个语句之后的两个 console.log 语句中,window/why 显示为文档中的 div?
为什么这些自动生成的变量不能像其他任何变量一样从它们的父对象中删除?
<!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>
I'd like to be able to delete these variables
绝对没有理由这样做。这些全局变量 are there for backwards compatibility 和浏览器几乎不会删除它们。但是,它们的创建方式使您可以简单地忽略它们 - 它们不会干扰您的任何变量。
只需在您的脚本中声明 var why;
,对元素的引用就会消失。
Why can't these automatically generated variables be deleted from their parent object?
首先,变量一般是不能删除的。只有对象属性可以——只是有些全局变量是全局对象的可删除属性。
元素引用可能无法删除,因为 a) 它们不是真正的属性而是代理 b) 它们不是全局对象本身的属性,而是其原型的属性或 c) 它们是属性全局范围内的额外变量记录。就当他们是魔法,不在乎了。
那是因为这些属性没有直接存储在window
中。相反,它的行为就像一个代理。
例如,当您在 WindowProperties
上使用 getOwnPropertyDescriptor
(window
从中继承)时,请参阅 what Firefox does:
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;
}
// ...
}
您可能会认为,当您为某个元素设置 ID 时,Firefox 会将其存储为全局 属性。但它不是这样工作的:当您尝试访问 属性 时,Firefox 将使用 GetElementById
来了解是否存在具有该 ID 的元素,并做出相应的回答。
更重要的是,deletions 被明确禁止:
bool WindowNamedPropertiesHandler::delete_(
JSContext* aCx, JS::Handle<JSObject*> aProxy,
JS::Handle<jsid> aId, JS::ObjectOpResult &aResult
) const {
return aResult.failCantDeleteWindowNamedProperty();
}
此行为是硬编码的,您无法阻止它。因此,如果这些属性让您烦恼,只需通过声明您自己的变量来覆盖它们。