javascript 有垃圾回收机制,所以一般情况下不需要程序猿手动delete对象,但是对于一些特殊情况,程序猿也需要使用delete。
1. delete是删除变量,而不是删除对象。如果delete 是删除对象,就会导致“悬挂指针”问题
2. 本质上,delete 删除的是对象的属性,而不是对象。
为了理解delete,需要引入执行上下文(Execution Context)和Activation Object/Variable Object。
在js中,可执行代码的类型有3种,函数代码,全局代码,eval代码。
- 全局代码:在全局作用域中执行的代码,类似于c语言中的main函数中的代码。
- 函数代码: 定义在函数中的代码。
- eval代码: 在eval(...)中执行的代码。
对于以上三种代码,都有对应的执行上下文,执行上下文类似于c语言中的堆栈。
而,每一个执行上下文都对应一个Activation Object / Variable Object,在每个执行上下文中,所有的变量定义,都是作为这个对象的属性存在。
比如:
- 全局代码中的变量: 是作为全局对象的属性存在,在客户端js中,全局对象是window。
- 函数代码中的变量: 是每次函数调用时,创建的Activation Object对象的属性。
- eval代码的变量: 该代码段的Activation Object是它存在的上下文的Activation Object,比如:在函数中使用eval语句,eval的Activation Object 就是该函数调用的Activation Object ,在全局代码调用eval就是全局对象。
这样,我们把所有的delete 操作都统一到对象属性的操作。
3.什么情况下,可以正确delete
每个对象属性都有一些标记来确定这个对象属性的种类。比如:ReadOnly, DontEnum, DontDelete, Internal。
DontDelete决定该属性是否可以Delete。
在变量声明的时候,DontDelete标记就已经确定,并且不能改变。
总结:
- 变量和函数的声明实际上都会成为全局对象或者当前函数活动对象的属性。
- 属性都有一个DontDelete标记,用于表明该属性是否能被delete。
- 变量和函数的声明创建的属性都会带有DontDelete标记。
- 函数内建的arguments对象作为该函数活动对象的默认属性,创建时总会带有DontDelete标记。
- 在eval代码块中声明的变量和方法都不带有DontDelete标记。
- 对还不存在的变量或属性的直接赋值产生的对象不会带有任何标记,包括DontDelete。
- 对于宿主对象而言,delete操作的结果有可能是不可预料的。
时间: 2024-10-05 04:04:45