之前看书的时候,看到通过var声明的全局变量不可以通过delete操作符删除。
然后,why?
How can I remember that?
so,I found some words;
首先,要了解window对象
window对象是BOM的核心。
那何为BOM?
bom,全称浏览器对象模型。他是操纵浏览器对象的,所以它提供了很多对象,用来访问浏览器的功能。查看高级程序设计的目录,BOM的二级目录有下面几个:
window对象,location对象,navigator对象,screen对象,history对象。
window对象就是我们的全局作用域,任何在全局作用域声明的变量和函数,都会变成window对象的属性和方法。
我们平时写的function 声明,也是同样建立window对象下:
var age = 10; function sayAge(){ alert(this.age) console.log(this) } window.age // 10 sayAge() // 10
使用var 声明的全局变量无法用delete操作符删除。 通过var声明的变量和通过function声明的函数拥有DontDelete特性,无法被删除。
在全局或者函数代码中的变量和函数声明总是创建带有 DontDelete 特性的属性。
上面这句注意这几点:
- 在全局作用域或者函数代码中通过var或者function声明的,无法用delete删除,也就是带有名为[[Configurable]]的特性。参考高级程序设计P194;
- 单纯的eval中声明的变量或函数,可以删除
- 如果是在eval里面的函数中声明的,不可以删除。参考第一条,第一条的优先级最高。
优先级:全局作用域/函数代码 > eval 。归根结底,就是第一条,在全局作用域或者函数代码中通过var或者function声明的,无法用delete删除。
delete是普通运算符,会返回true或false。
规则为:当被delete的对象的属性存在并且拥有DontDelete时 返回false,否则返回true。
if(属性存在 && 拥有DontDelete) return true;
else return false;
这里的一个特点就是,对象属性不存在时也返回true,所以返回值并非完全等同于删除成功与否。
所以,不要单纯的相信宿主对象对你造作的返回结果。
摘自:http://bubkoo.com/2014/01/23/deep-in-delete/
下面是对于 JavaScript 中 delete 操作是如何工作的简短的总结:
- 变量和函数声明都是活化对象(Activation Object) 或全局对象(Global Object)的属性
- 属性拥有内部属性,其中 DontDelete 这个内部属性负责确定一个属性是否能够被删除
- 在全局或者函数代码中的变量和函数声明总是创建带有 DontDelete 特性的属性
- 函数参数总是活动对象的属性, 并且带有 DontDelete
- 在 Eval 代码中声明的变量和函数总是创建不带 DontDelete 特性 的属性
- 新的未声明的属性在生成时带空的内部属性,因此也不带 DontDelete 特性
- 永远不要相信宿主对象对 delete 操作做出的反应