javascript 中的 delete及delete运算符


Posted in Javascript onNovember 15, 2015

那么,为什么我们能删除一个对象的属性:

var x = { a: 1 };
delete x.a; // true
x.a; // undefined

但却不能删除一个变量:

var x = 1;
delete x; // false;
x; // 1

也不能删除一个函数:

function x() {};
delete x; // false;
typeof x; // "function"

注意:delete 只有当一个属性无法被删除时才返回 false。

 每一个属性拥有零至多个如内部属性——*ReadOnly,DontEnum,DontDelete和Internal**。 你可以把它们想象为标签——一个属性可能拥有也可能没有某个特殊的内部属性。 在今天的讨论中,我们所感兴趣的是 DontDelete。

当声明变量和函数时,它们成为了变量对象(Variable object)——要么是活化对象(在函数代码中), 要么是全局对象(在全局代码中)——的属性,这些属性伴随生成了内部属性 DontDelete。 然而,任何显式/隐式赋值的属性不生成 DontDelete。 而这就是本质上为什么我们能删除一些属性而不能删除其他的原因。

var GLOBAL_OBJECT = this;

/* 'foo'是全局对象的一个属性,它通过变量声明而生成,因此拥有内部属性DontDelete

这就是为什么它不能被删除*/

var foo = 1;
delete foo; // false
typeof foo; // "number"
/* 'bar

'是全局对象的一个属性,它通过变量声明而生成,因此拥有DontDelete子

这就是为什么它同样不能被删除*/

function bar() {};
delete bar; // false
typeof bar; // "function"

/* 'baz'也是全局对象的一个属性,

然而,它通过属性赋值而生成,因此没有DontDelete

这就是为什么它可以被删除*/

GLOBAL_OBJECT.baz = "baz";
delete GLOBAL_OBJECT.baz; // true
typeof GLOBAL_OBJECT.baz; // "undefined"

1.5、内建和DontDelete | Build-ins and DontDelete

所以这就是所有这一切发生的原因:属性的一个特殊的内部属性控制着该属性是否可以被删除。 注意:内建对象的一些属性拥有内部属性 DontDelete,因此不能被删除; 特殊的 arguments 变量(如我们所知的,活化对象的属性)拥有 DontDelete; 任何函数实例的 length (返回形参长度)属性也拥有 DontDelete:

(function() {
  //不能删除'arguments',因为有DontDelete
  delete arguments; // false;
  typeof arguments; // "object"

  //也不能删除函数的length,因为有DontDelete
  function f() {};
  delete f.length; // false;
  typeof f.length; // "number"
}) ();

与函数 arguments 相关联的属性也拥有 DontDelete,同样不能被删除

(function(foo,bar) {
  delete foo; // false
  foo; // 1

  delete bar; // false
  bar; // "bah"
}) (1,"bah");

1.6、未声明的变量赋值 | Undeclared assignments

你可能记得,未声明的变量赋值会成为全局对象的属性,除非这一属性在作用域链内的其他地方被找到。 而现在我们了解了属性赋值和变量声明的区别——后者生成 DontDelete 而前者不生成——这也就是为什么未声明的变量赋值可以被删除的原因了。

var GLOBAL_OBJECT = this;

/* 通过变量声明生成全局对象的属性,拥有DontDelete */
var foo = 1;

/* 通过未声明的变量赋值生成全局对象的属性,没有DontDelete */
bar = 2;
delete foo; // false
delete bar; // true

注意:内部属性是在属性生成时确定的,之后的赋值过程不会改变已有的属性的内部属性。 理解这一区别是重要的。

/* 'foo'创建的同时生成DontDelete */
function foo() {};
/* 之后的赋值过程不改变已有属性的内部属性,DontDelete仍然存在 */
foo = 1;
delete foo; // false;
typeof foo; // "number"
/* 但赋值一个不存在的属性时,创建了一个没有内部属性的属性,因此没有DontDelete */
this.bar = 1;
delete bar; // true;
typeof bar; // "undefined"

总结:

变量和函数声明都是活化(Activation)全局(Global)对象的属性。

属性拥有内部属性,其中一个—— DontDelete 负责确定一个属性是否能够被删除。

全局代码或函数代码中的变量、函数声明都生成拥有 DontDelete 的属性。

函数参数同样是活化对象的属性,也拥有 DontDelete。

删除对象中的属性:delete 对象.成员

          只能删除自有的成员

          只有var声明的全局变量不让delete

          使用window.或window[""]增加的全局成员可以delete

ps:Javascript中delete运算符

Delete是Javascript语言中使用频率较低的操作之一,但是有些时候,当我们需要做delete或者清空动作时,就需要delete操作。在这篇文章中,我们将深入探讨如何使用它,以及它是如何工作的。

删除的目的,如你所想,就是要删除某些东西,更具体的说,它会删除对象的属性,如下例:

var Benjamin = {
  "name": "zuojj",
  "url" : "http://www.zuojj.com"
};
delete Benjamin.name;
//Outputs: Object { url: "http://www.zuojj.com" }
console.log(Benjamin);

delete运算符将不会删除普通变量,如下例:

var benjamin = "http://www.zuojj.com";
delete benjamin;
//Outputs: "http://www.zuojj.com"
console.log(benjamin);

但是,它可以删除“全局变量”,因为它们事实上是全局对象(浏览器中是window)对象的属性。

// Because var isn't used, this is a property of window
benjamin = "zuojj";
delete window.benjamin;
// ReferenceError: benjamin is not defined
console.log(benjamin);

delete运算符也有一个返回值,如果删除一个属性成功了,返回true,如果不能删除属性,因为该属性是不可写,将返回false,或者如果在严格模式下会抛出一个错误。

var benjamin = {
  "name": "zuojj",
  "url" : "http://www.zuojj.com"
};
var nameDeleted = delete benjamin.name;
// Outputs: true
console.log(nameDeleted);
"use strict";
var benjamin_ = "zuojj";
//Outputs: Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
delete benjamin_;

你可能不知道在什么情况下使用删除运算符。答案是,只要你真的想从对象中删除一个属性。

有的时候,Javascript开发不是删除一个属性,而是把这个属性值设置为null.像下面这样:

var benjamin = {
  "name": "zuojj",
  "url" : "http://www.zuojj.com"
};
benjamin.name = null;

虽然这有效地切断从原来的值的属性,但该属性本身仍然存在的对象上,你可以看到如下:

// Outputs: Object { name: null, url: "http://www.zuojj.com" }
console.log(benjamin);

同时,像in和for in 循环运算将不会报告null属性的存在,如果你使用个对象,可能使用这些方法来检查一个对象,你可能想确保你真正删除任何不需要的属性。

最后,你应该记住,删除并没有破坏属性的值,仅仅属性本身,看下面的例子:

var name   = "zuojj",
    benjamin = {};
benjamin.name = name;
delete benjamin.name;
//Outputs: "zuojj"
console.log(name);

这里,name和benjamin.name映射到相同的值,真如你所看到的,删除benjamin.name并不会影响name.

以上,就是我对delete运算符的概述,不妥之处,欢迎大家批评指正。

Javascript 相关文章推荐
js几个不错的函数 $$()
Oct 09 Javascript
javascript 读取图片文件的大小
Jun 25 Javascript
学习JS面向对象成果 借国庆发布个最新作品与大家交流
Oct 03 Javascript
jQuery中removeProp()方法用法实例
Jan 05 Javascript
JavaScript中this的9种应用场景及三种复合应用场景
Sep 12 Javascript
JavaScript实现的浏览器下载文件的方法
Aug 09 Javascript
jquery鼠标悬停导航下划线滑出效果
Sep 29 jQuery
React Native 真机断点调试+跨域资源加载出错问题的解决方法
Jan 18 Javascript
基于express中路由规则及获取请求参数的方法
Mar 12 Javascript
vue写一个组件
Apr 09 Javascript
layer.close()关闭进度条和Iframe窗的方法
Aug 17 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
Oct 12 Javascript
详解JavaScript函数对象
Nov 15 #Javascript
javascript中window.open在原来的窗口中打开新的窗口(不同名)
Nov 15 #Javascript
深入浅析JavaScript中prototype和proto的关系
Nov 15 #Javascript
apply和call方法定义及apply和call方法的区别
Nov 15 #Javascript
JavaScript和HTML DOM的区别与联系及Javascript和DOM的关系
Nov 15 #Javascript
WEB前端开发都应知道的jquery小技巧及jquery三个简写
Nov 15 #Javascript
JS使用eval解析JSON的注意事项分析
Nov 14 #Javascript
You might like
php set_time_limit(0) 设置程序执行时间的函数
2010/05/26 PHP
YII框架批量插入数据的方法
2017/03/18 PHP
PHP操作MySQL中BLOB字段的方法示例【存储文本与图片】
2017/09/15 PHP
php反射学习之依赖注入示例
2019/06/14 PHP
JavaScript 解析读取XML文档 实例代码
2009/07/07 Javascript
JavaScript OOP类与继承
2009/11/15 Javascript
JQuery1.4+ Ajax IE8 内存泄漏问题
2010/10/15 Javascript
关于图片按比例自适应缩放的js代码
2011/10/30 Javascript
JavaScript var声明变量背后的原理示例解析
2013/10/12 Javascript
用JS生成UUID的方法实例
2016/03/30 Javascript
DIV随滚动条滚动而滚动的实现代码【推荐】
2016/04/12 Javascript
用JS实现图片轮播效果代码(一)
2016/06/26 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
jQueryUI Datepicker组件设置日期高亮
2016/10/13 Javascript
Bootstrap如何创建表单
2016/10/21 Javascript
JavaScript实现数组降维详解
2017/01/05 Javascript
使用vue.js写一个tab选项卡效果
2017/03/25 Javascript
vue给组件传递不同的值方法
2018/09/29 Javascript
nodejs对项目下所有空文件夹创建gitkeep的方法
2019/08/02 NodeJs
[56:01]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 Effect vs EG
2018/03/31 DOTA
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
2015/05/22 Python
详解使用python的logging模块在stdout输出的两种方法
2017/05/17 Python
Python3使用Matplotlib 绘制精美的数学函数图形
2019/04/11 Python
python3使用print打印带颜色的字符串代码实例
2019/08/22 Python
Python使用Pandas库常见操作详解
2020/01/16 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
CSS3 真的会替代 SCSS 吗
2021/03/09 HTML / CSS
WoolOvers爱尔兰:羊绒、羊毛和棉针织品
2017/01/04 全球购物
英国工作场所设备购买网站:Slingsby
2019/05/03 全球购物
Kathmandu新西兰官网:新西兰户外运动品牌
2019/07/27 全球购物
P D PAOLA意大利官网:西班牙著名的珠宝首饰品牌
2019/09/24 全球购物
九九重阳节致辞
2015/07/31 职场文书
《金色的草地》教学反思
2016/02/17 职场文书
OpenCV-Python实现图像平滑处理操作
2021/06/08 Python
Vue.js中v-for指令的用法介绍
2022/03/13 Vue.js
Python tensorflow卷积神经Inception V3网络结构
2022/05/06 Python