JavaScript delete操作符应用实例


Posted in Javascript onJanuary 13, 2009

今天在看prototype代码时发现了delete这个操作符

unset: function(key) { 
var value = this._object[key]; 
delete this._object[key]; 
return value; 
}

查了一下手册,
delete 运算符
从对象中删除一个属性,或从数组中删除一个元素。
delete expression
expression 参数是一个有效的 JScript 表达式,通常是一个属性名或数组元素。
说明
如果 expression 的结果是一个对象,且在 expression 中指定的属性存在,而该对象又不允许它被删除,则返回 false。
在所有其他情况下,返回 true。
看到“从数组中删除一个元素”感觉不错,可ff里试了一下,似乎只能删除那个元素的值,而不是元素本身。不过从对象中删除一个属性是可以的。
又google了一下,发现有一篇文章讲得很详细,转载过来以免忘记:
Javascript的变量
实际上Javascript中,变量 = 对象属性,这是因为 Javascript 在执行脚本之前会创建一个Global对象,所有的全局变量都是这个Global对象的属性,执行函数时也会创建一个Activation对象,所有的局部变量都是这个Activation对象的属性。如下例:
var global = 42; 
this.global; // 42, 可以通过this来访问Global对象 
this.global2 = 12; 
global2; // 12 
function foo() { 
var local = 36; 
// 不过无法直接访问Activation, 
// 因此无法通过 foo.local 的方式来访问local变量 
}

delete操作符删除的对象
C++中也有delete操作符,它删除的是指针所指向的对象。例如:
// C++ 
class Object { 
public: 
Object *x; 
} 
Object o; 
o.x = new Object(); 
delete o.x; // 上一行new的Object对象将被释放

但Javascript的delete与C++不同,它不会删除o.x指向的对象,而是删除o.x属性本身。
// Javascript 
var o = {}; 
o.x = new Object(); 
delete o.x; // 上一行new的Object对象依然存在 
o.x; // undefined,o的名为x的属性被删除了

在实际的Javascript中,delete o.x之后,Object对象会由于失去了引用而被垃圾回收,所以delete o.x也就“相当于”删除了o.x所指向的对象,但这个动作并不是ECMAScript标准,也就是说,即使某个实现完全不删除Object对象,也不算是违反ECMAScript标准。
“删除属性而不是删除对象”这一点,可以通过以下的代码来确认。
var o = {}; 
var a = { x: 10 }; 
o.a = a; 
delete o.a; // o.a属性被删除 
o.a; // undefined 
a.x; // 10, 因为{ x: 10 } 对象依然被 a 引用,所以不会被回收

另外,delete o.x 也可以写作 delete o["x"],两者效果相同。
对变量执行delete的情况
由于变量也是 Global 或者是 Activation 对象的属性,所以对变量的delete操作也是同样的结果。
var global = 42; 
delete global; // 删除Global.global 
function foo() { 
var local = 36; 
delete local; // 删除Activation.local 
}

能删除的属性和不能删除的属性
并不是所有的属性都能被delete。例如,prototype中声明的属性就无法被delete:
function C() { this.x = 42; } 
C.prototype.x = 12; 
var o = new C(); 
o.x; // 42, 构造函数中定义的o.x 
delete o.x; 
o.x; // 12, prototype中定义的o.x,即使再次执行delete o.x也不会被删除

对象的预定义属性也无法删除。 可以认为这类属性带有DontDelete的特性。
var re = /abc/i; 
delete re.ignoreCase; 
re.ignoreCase; // true, ignoreCase无法删除

能删除的变量和不能删除的变量
通过var声明的变量和通过function声明的函数拥有DontDelete特性,无法被删除。
var x = 36; 
delete x; 
x; // 36, x没有被删除 
y = 12; 
delete y; 
y; // undefined 
function foo() { return 42; } 
delete foo; 
foo(); // 42

但是有一点例外,就是通过 eval 执行的代码中,通过var声明的变量虽然与正常的var声明变量同属于Global对象,但它们不具有DontDelete特性,能被删除。
eval("var x = 36;"); 
x; // 42 
delete x; 
x; // undefined

但是这也有一点例外,eval的代码中的函数内通过var定义的变量具有DontDelete,不能被删除。
eval("(function() { var x = 42; delete x; return x; })();"); 
// 返回 42

delete的返回值
delete是普通运算符,会返回true或false。规则为:当被delete的对象的属性存在并且拥有DontDelete时返回false,否则返回true。这里的一个特点就是,对象属性不存在时也返回true,所以返回值并非完全等同于删除成功与否。
function C() { this.x = 42; } 
C.prototype.y = 12; 
var o = new C(); 
delete o.x; // true 
o.x; // undefined 
"x" in o; // false 
// o.x存在并且没有DontDelete,返回true 
delete o.y; // true 
o.y; // 12 
// o自身没有o.y属性,所以返回true 
// 从这里也可以看到prototype链的存在,对象自身属性和prototype属性是不同的 
delete o; // false 
// Global.o拥有DontDelete特性所以返回false 
delete undefinedProperty; // true 
// Global没有名为undefinedProperty的属性因此返回true 
delete 42; // true 
// 42不是属性所以返回true。有的实现会抛出异常(违反ECMAScript标准) 
var x = 24; 
delete x++; // true 
x; // 25 
// 被删除的是x++的返回值(24),不是属性,所以返回true
Javascript 相关文章推荐
JavaScript CSS修改学习第一章 查找位置
Feb 19 Javascript
分享27个jQuery 表单插件集合推荐
Apr 25 Javascript
js函数中onmousedown和onclick的区别和联系探讨
May 19 Javascript
工作中常用的js、jquery自定义扩展函数代码片段汇总
Dec 22 Javascript
jQuery实现动态文字搜索功能
Jan 05 Javascript
深入理解Vue 的条件渲染和列表渲染
Sep 01 Javascript
微信小程序实现topBar底部选择栏效果
Jul 20 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
Jul 27 Javascript
解决webpack dev-server不能匹配post请求的问题
Aug 24 Javascript
Vue中 v-if 和v-else-if页面加载出现闪现的问题及解决方法
Oct 12 Javascript
JavaScript实现省市区三级联动
Feb 13 Javascript
微信小程序 根据不同用户切换不同TabBar
Apr 21 Javascript
在网页里看flash的trace数据的js类
Jan 10 #Javascript
捕获关闭窗口的脚本
Jan 10 #Javascript
javascript 自动转到命名锚记
Jan 10 #Javascript
Javascript 生成指定范围数值随机数
Jan 09 #Javascript
Js 订制自己的AlertBox(信息提示框)
Jan 09 #Javascript
通用JS事件写法实现代码
Jan 07 #Javascript
javascript 表单的友好用户体现
Jan 07 #Javascript
You might like
PHP imagecreatefrombmp 从BMP文件或URL新建一图像
2012/07/16 PHP
PHP加密扩展库Mcrypt安装和实例
2013/11/10 PHP
PHP开发微信支付的代码分享
2014/05/25 PHP
ThinkPHP框架设计及扩展详解
2014/11/25 PHP
yii实现model添加默认值的方法(2种方法)
2016/01/06 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
PHP中register_shutdown_function函数的基础介绍与用法详解
2017/11/28 PHP
php中try catch捕获异常实例详解
2020/08/06 PHP
JQuery文本框高亮显示插件代码
2011/04/02 Javascript
jQuery UI AutoComplete 使用说明
2011/06/20 Javascript
js实现局部页面打印预览原理及示例代码
2014/07/03 Javascript
JavaScript简单表格编辑功能实现方法
2015/04/16 Javascript
jquery 重写 ajax提交并判断权限后 使用load方法报错解决方法
2016/01/19 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
常用的js验证和数据处理总结
2016/08/02 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
微信小程序 刷新上拉下拉不会断详细介绍
2017/05/11 Javascript
详解Angular Forms中自定义ngModel绑定值的方式
2018/12/10 Javascript
如何根据业务封装自己的功能组件
2019/04/19 Javascript
JS算法题之查找数字在数组中的索引位置
2019/05/15 Javascript
微信小程序进入广告实现代码实例
2019/09/19 Javascript
Vue3 的响应式和以前有什么区别,Proxy 无敌?
2020/05/20 Javascript
用实例详解Python中的Django框架中prefetch_related()函数对数据库查询的优化
2015/04/01 Python
Python基础入门之seed()方法的使用
2015/05/15 Python
对PyQt5中树结构的实现方法详解
2019/06/17 Python
Python实现直播推流效果
2019/11/26 Python
PyTorch 普通卷积和空洞卷积实例
2020/01/07 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
2020/02/13 Python
通过实例简单了解python yield使用方法
2020/08/06 Python
什么是继承
2013/12/07 面试题
最新的咖啡店创业计划书
2013/12/30 职场文书
求职自荐信的格式
2014/04/07 职场文书
工厂仓管员岗位职责范本
2014/07/17 职场文书
职代会闭幕词
2015/01/28 职场文书
2016年暑期见闻作文
2015/11/25 职场文书
一波干货,会议主持词开场白范文
2019/05/06 职场文书