javascript中delete方法的使用方法

delete 运算符

从对象中删除一个属性,或从数组中删除一个元素。

delete expression

expression 参数是一个有效的 JScript 表达式,通常是一个属性名或数组元素。

说明

如果 expression 的结果是一个对象,且在 expression 中指定的属性存在,而该对象又不允许它被删除,则返回 false。

在所有其他情况下,返回 true。

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"],两者效果相同。

能删除的变量和不能删除的变量

通过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

 

对变量执行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无法删除

JavaScript的垃圾回收是浏览器自行处理的,对于字符串、对象、数据这些没有固定大小,必须为它们动态的分配内存,但什么时候回收这些内存呢?JavaScript使用和Java一样的垃圾回收的方法。程序员不能对此做过多的干预,JavaScript中的delete操作是用于删除对象中的域或者数组中的成员,如果要删除对象只需要将该对象设置为null或者undefined。

delete的用法

 代码如下 复制代码

delete obj.prop;

delete obj['prop'];

delete arr[i];

例子

 代码如下 复制代码

<script language="javascript">
var obj = new Object();
obj.className = 'instance';
obj.parent = 'Object';
obj.des = 'some words';
for(key in obj)
alert(obj[key]);
delete obj.des;
for(key in obj)
alert(obj[key]);
</script>

§ Deleting variables via eval(通过eval删除变量)

  最有意思的是eval的特性, 另一方面ECMAScript能从技术上允许我们去删除不可删除的属性.在同一个上下文中function的声明是可以被同名变量重写的.

 代码如下 复制代码
 function x(){ }
 var x;
 typeof x; // "function"

注意 function声明优先,重写同名变量(或者, 换句话说, 在变量对象中存在了相同属性). 这是因为 函数声明被实例是在变量声名(Variable declarations)之后, 是允许被覆盖的不仅函数声明替换这前属性的值, 它也能替换它的属性.

如果我们通过eval来声明function那么还是可以替换相应的属性, 因为在eval里创建的变量声明没有DontDelete, 以下示例会从本质上删除存在的DontDelete特性。

 代码如下 复制代码

var x = 1;
  /* Can't delete, `x` has DontDelete */
 
  delete x; // false
  typeof x; // "number"
  eval('function x(){}');
  /* `x` property now references function, and should have no DontDelete */
 
  typeof x; // "function"
  delete x; // should be `true`
  typeof x; // should be "undefined"

不幸的事,  我尝试各种不能工作的场景, 有可能我会有所疏漏.

其他不能被删除的属性

除了上面说过的内置属性(即预定义属性)不能被删除外,prototype中声明的属性也不能delete:

 代码如下 复制代码

function C() { this.x = 42; }
C.prototype.x = 12;
C.prototype.y = 13;

var o = new C();
o.x; // 42, 构造函数中定义的o.x

delete o.x; //true 删除的是自身定义的x
o.x; // 12, prototype中定义的o.x,即使再次执行delete o.x也不会被删除

delete o.y; //true,因为 o自身没有o.y属性,y存在于prototype链中,也就是说对象自身属性和prototype属性是不同的
o.y; //13

 

时间: 2024-09-22 00:03:26

javascript中delete方法的使用方法的相关文章

JavaScript中关键字 in 的使用方法详解_javascript技巧

for-in循环应该用在非数组对象的遍历上,使用for-in进行循环也被称为"枚举". 对于数组 ,迭代出来的是数组元素 但不推荐,因为不能保证顺序,而且如果在Array的原型上添加了属性,这个属性也会被遍历出来,所以 最好数组使用正常的for循环,对象使用for-in循环 对于对象 ,迭代出来的是对象的属性: var obj = { "key1":"value1", "key2":"value2", &q

JavaScript中数组的22种方法必学(推荐)_javascript技巧

前面的话 数组总共有22种方法,本文将其分为对象继承方法.数组转换方法.栈和队列方法.数组排序方法.数组拼接方法.创建子数组方法.数组删改方法.数组位置方法.数组归并方法和数组迭代方法共10类来进行详细介绍 对象继承方法 数组是一种特殊的对象,继承了对象Object的toString().toLocaleString()和valueOf()方法 [toString()] toString()方法返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串 [注意]该方法的返回值与不使用任何参数

注意JavaScript中RegExp对象的test方法

javascript|对象 javascript 中的 RegExp 对象用于正则表达式相关的操作,这个对象提供了一个方法 test 来判定某个字符串是否满足某个 pattern. 返回值是 true/false.今天我碰到了一个问题: <script type="text/javascript"><!--var re = /^\d+(?:\.\d)?$/ig;    alert(re.test('112.3'));alert(re.test('33'));//--&

在JavaScript中处理字符串之fontcolor()方法的使用

  这篇文章主要介绍了在JavaScript中处理字符串之fontcolor()方法的使用,是JS入门学习中的基础知识,需要的朋友可以参考下 此方法会导致就好像它是在一个字符串被显示在指定的颜色 标记. 语法 ? 1 string.fontcolor( color ) 下面是参数的详细信息: color: 字符串表示的颜色为十六进制RGB三元或作为一个字符串 返回值: 字符串表示的颜色为十六进制RGB三元或作为一个字符串 例子: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 1

在JavaScript中处理字符串之link()方法的使用

  这篇文章主要介绍了在JavaScript中处理字符串之link()方法的使用,是JS入门学习中的基础知识,需要的朋友可以参考下 此方法创建了请求另一个URL的HTML超文本链接. 语法 ? 1 string.link( hrefname ) 下面是参数的详细信息: hrefname: 任何字符串指定HREF标记; 它应该是一个有效的URL 返回值: 返回字符串标签 例子: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <html> <head> &

JavaScript中操作字符串之localeCompare()方法的使用

  这篇文章主要介绍了JavaScript中操作字符串之localeCompare()方法的使用,是JS入门学习中的基础知识,需要的朋友可以参考下 这个方法返回一个数字表示参考字符串是否到来之前或之后或相同的排序顺序给定的字符串. 语法 ? 1 string.localeCompare( param ) 下面是参数的详细信息: param : 字符串对象进行比较的字符串 返回值: 0 : 字符串匹配100% 1 : 不匹配,参数值来自于语言环境的排序顺序字符串对象的值之前 -1 : 不匹配,参数

JavaScript中length属性的使用方法

  这篇文章主要介绍了JavaScript中length属性的使用方法,是JS入门学习中的基础知识,需要的朋友可以参考下 此属性返回字符串中的字符数. 语法 ? 1 string.length 下面是参数的详细信息: A string 返回值: 返回字符串中的字符数. 例子: ? 1 2 3 4 5 6 7 8 9 10 11 <html> <head> <title>JavaScript String length Property</title> <

在JavaScript中使用NaN值的方法

  这篇文章主要介绍了在JavaScript中使用NaN值的方法,是JS入门学习中的基础知识,需要的朋友可以参考下 不带引号的字面常量NaN是一个特殊的值,表示不是非数字.由于NaN总是比较不等的情况,以任何数,包括NaN,它通常是用于指示应该返回一个有效的数的函数的错误条件. 注意:使用isNaN()全局函数来查看是否值是NaN值. 语法 您可以使用以下语法访问属性: ? 1 var val = Number.NaN; 示例 : 在这里,dayOfMonth分配NaN,如果是大于31,并显示一

javascript中自定义对象的属性方法分享

这篇文章介绍了在javascript中自定义对象的属性方法,有需要的朋友可以参考一下   首先介绍下关联数组: 复制代码 代码如下: <script> var test=new Object(); test["a"]=1; test["b"]="string"; test["c"]=false; alert(test["a"]); </script> 执行上面的代码,显示1. 在ja

JavaScript中消除闭包的一般方法介绍

 这篇文章主要介绍了JavaScript中消除闭包的一般方法介绍,本文直接给出了操作示例,需要的朋友可以参考下     JavaScript 的闭包是一个其主动发展的特性, 也是一个被动发展的特性. 也就是说, 一方面, JS 有了闭包能更好解决一些问题. 另一方面, JS 为了解决某些问题, 而不得不使用闭包勉强来解决问题. 前者这里不讨论, 如果 JS 闭包能更好的解决问题, 当然使用闭包更好. 我讨论的是后者, 是因为 JS 本身的限制, 而不得不磕磕绊绊地用闭包来解决的问题, 例如"变量