10

根据这个 MDN 页面delete关键字

仅当属性存在且无法删除时才返回 false。它在所有其他情况下返回 true。

但是,我看到了delete返回的情况true,尽管该属性没有被删除:

delete Window
delete alert
delete dir
delete console
delete 2
delete null
delete {}.x
...

事实上,几乎所有的属性都window返回 true with delete,通过在 中运行以下脚本可以看出about:blank

for(a in window) { if(delete window[a]) { console.log(a); } }

但是,大多数属性window实际上并没有被删除。的返回值的真正含义是delete什么?为什么它会返回true它不删除的属性?

(注意:我会对解释 . 行为的 Chromium 代码的引用感兴趣delete。)

4

5 回答 5

8

窗口是一个宿主对象,其语义由宿主环境(例如浏览器)定义。 delete当应用于宿主对象的属性时,比应用于本机对象时更复杂。

宿主对象可以通过任何依赖于实现的行为来支持这些内部属性,只要它与本文档中所述的特定宿主对象限制一致。

第 11.4.1 节 -delete操作员

If IsUnresolvableReference(ref) then,
  If IsStrictReference(ref) is true, throw a SyntaxError exception.
  Else, return true.

因此,当宿主对象不支持删除或修改属性时,它会返回无法解析的引用或假装被删除的引用。任何一种方法都会导致true以非严格模式返回。

于 2012-08-27T16:48:16.307 回答
2

浏览器使用的 javascript 实现一直在打破规则。部分 javascript DOM API 在纯 javascript 中甚至是不可能的,例如触发事件的 dom innerHTML="something"。这在 EcmaScript5 中已修复,但您不能依赖浏览器对象模型是 100% 合法的 javascript。AFAIK,只要您不涉足 DOM 和 BOM,您就可以完全依赖 ecmascript 标准。

于 2012-09-07T11:00:42.803 回答
1

鉴于您正在对程序中的低级对象进行操作,这些属性实际上可能会被删除然后立即重新添加,尽管我不知道您如何测试这种行为。

于 2012-08-27T16:36:50.363 回答
1

在那个 MDN 页面上,它指定了语法,不包括delete object您的第一组示例使用的语法。delete object[property]它确实指定了第二个示例所示的语法。但是,没有指定 DOM(主机)对象会发生什么。有关详细信息,请参阅本文

于 2012-08-27T16:45:21.307 回答
0

基本上,在您的测试中,浏览器正在保护浏览器的运行时环境。

曾几何时,情况可能并非如此,但就测试而言,这类似于问为什么 Windows 不允许您打开命令外壳并运行:

> cd /
> deltree *.*

了。

因为确实没有充分的理由能够做这样的事情,所以当您期望环境在之后实际继续运行时,并且不会关闭您的整个浏览器,以及您当前正在使用的操作系统实例运行,或者当您基本上要求程序实时擦除自身时可能会发生任何其他有趣的错误,而它目前对您的 GPU/声卡/输入设备具有低级访问权限。

如果您尝试删除 var,Delete 将返回失败。就浏览器需要运行的全局属性而言,它们中的大多数都被定义为属性(即:)window.location,但都是在低级别完成的(即:您无权访问)。所以理论上,它们是可以删除的对象。但是它们是受保护的,所以你不能,但这不会改变 的 return 语句delete,因为这会改变delete' 的预期行为。

所以:

function () {
    var obj = { prop : true };
    delete obj; /* fail */
    delete object.prop; /* succeed */
}
于 2012-08-27T16:49:34.580 回答