误区
理解事物为什么那么工作是一种难以言说的美,我在网上已经看到了与delete 运算符误解相关的误区。例如,在关于栈溢出的回答(评分出其不意的效果高)中,它自信的解释道:“delete is supposed to be no-op when target isn’t an object property ”。现在,我们已经理解了delete 行为的核心,很清楚这个答案是不准确的。delete 不区分变量和属性(事实上,对于删除,这些都是引用),真正的只关心的是DontDelete特性(和属性存在)。
非常有意思的看到这个误解如何相互影响,在同样一个线程中,有人首先提出要直接删除变量(除非它是在eval 中声明,否则不会生效),接着另外一个人提出一种错误的纠正方法--在全局中可能删除变量,但在函数内不行。
在网站上解释Javascript 最好小心,最好总是抓住问题的核心。
‘delete’和宿主对象
delete 的算法大概是这样:
- 如果操作不是一个引用,返回
true ;
- 如果一个对象没有直接的属性,返回
true ;(我们知道,对象可以是激活对象,可以是全局象);
- 如果一个属性存在并有DontDelete特性,返回
false ;
- 否则,删除属性并返回
true ;
但是,宿主对象的delete 运算符的行为难以预测。实际上并没有错:除了少数几个,宿主对象是允许执行任何类型的运算行为的(按规范),如read(内部的[get]方法)、write(内部的[put]方法)或delete (内部的[delete]方法)。这个定制的[[Delete]]行为使得宿主对象如此混乱。
在IE中我们已经看到一些古怪的行为,如果删除某些对象(明显作为宿主对象来执行)将抛出错误。Firefox的一些版本在尝试删除window.location 时将抛出错误。当涉及到宿主对象时,你不能信任delete 返回的任何值。看看在Firefox会有什么发生:
/* "alert" is a direct property of `window` (if we were to believe `hasOwnProperty`) */
window.hasOwnProperty( 'alert' ); // true
delete window.alert; // true
typeof window.alert; // "function"
删除window.alert 返回true ,虽然这个属性什么也没有,它应该导致这个结果。它保留了一个引用(因此在第一步中不应该返回true ),它是窗口对象的直接属性(因此第二步中不能返回true)。唯一的办法让delete 返回true 是在第四步之后真正删除属性。但是,属性是永远不会被删除的。
这个故事的寓意在于永远不要相信宿主对象
ES5严格模式
那么,ECMAScript 5th edition 的严格模式可以拿到台面上来了。一些限制正被引入,当delete 运算符是一个变量、函数参数或函数标识符的直接引用时将抛出SyntaxError。另外,如果属性内部有[[Configurable]] == false,将抛出TypeError。 ( function (foo){
"use strict" ; // enable strict mode within this function
var bar;
function baz(){}
delete foo; // SyntaxError (when deleting argument)
delete bar; // SyntaxError (when deleting variable)
delete baz; // SyntaxError (when deleting variable created with function declaration)
/* `length` of function instances has { [[Configurable]] : false } */
delete ( function (){}).length; // TypeError
})();
另外,删除未声明的变量(换句话说,没有找到的引用)也抛出SyntaxError。 "use strict" ;
delete i_dont_exist; // SyntaxError
正如你所理解的那样,考虑到删除变量、函数声明和参数会导致如此多得混淆,所有这些限制就有点意义。与不声不响的忽略删除行为相反,严格模式应该采取更积极的、更具有描述性的措施。
出处:Denis'Blog
责任编辑:bluehearts
上一页 理解delete [6] 下一页 理解delete [8]
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|