Heim  >  Artikel  >  Web-Frontend  >  解析JavaScript中delete操作符不能删除的对象_javascript技巧

解析JavaScript中delete操作符不能删除的对象_javascript技巧

WBOY
WBOYOriginal
2016-05-16 17:10:561301Durchsuche

ES3 中,delete在8.6.2.5及11.4.1有介绍,如下

有一些信息,

1、实现上delete操作符会调用引擎内部的[[Delete]]方法

2、[[Delete]]在8.6.2里定义

3、删除的属性有个DontDelete的特性,如果有,delete时直接返回false

搜索“DontDelete”,会发现有很多,如下都不能delete

1, 激活对象的arguments对象 (10.1.6)

复制代码 代码如下:

function func() {
    delete arguments;
    alert(arguments);
}
func(1);

2,变量声明 (10.2.1)
复制代码 代码如下:

var a = 10;
delete a;
alert(a); // 10

这一条在很多JS书里有提及,即不能delete掉使用var声明的变量。

3,函数声明

复制代码 代码如下:

function func() {}
delete func;
alert(func); // func code

4,函数的length属性
复制代码 代码如下:

function func(a, b) {}
delete func.length;
alert(func.length); // 2

5,一些常量(NaN、Infinity、undefined)
复制代码 代码如下:

delete NaN; // false
delete Infinity; // false
delete undefined; // false

6,内置构造器的prototype
复制代码 代码如下:

delete Object.prototype; // false
delete Function.prototype; // false
delete Array.prototype; // false
delete ExpReg.prototype; // false
delete Date.prototype; // false
delete Error.prototype; // false
delete Number.prototype; // false
delete Boolean.prototype; // false
delete String.prototype; // false

7, 数组和字符串的length
复制代码 代码如下:

var arr = [], str = 'hello';
delete arr.length; // false
delete str.length; // false

8,Math对象的属性(Math.E、Math.LN10、Math.LN2、Math.LOG2E、Math.LOG10E、Math.PI、Math.SQRT1_2、Math.SQRT2)
复制代码 代码如下:

delete Math.E; // false
...

9,正则对象的属性(source、global、ignoreCase、multiline、lastIndex)
复制代码 代码如下:

var reg = /ss/;
delete reg.source; // false
...

ES5 与ES3不同,ES5中没有“DontDelete”,却增加了 [[Configurable]] (8.6.1)。

如果该值为false,则不能delete,以上列举的9点在ES5中描述为[[Configurable]]为false。

ES5新增的Object.defineProperty方法可显示的定义对象的Configurable,如下

复制代码 代码如下:

var obj = {name: 'John'};
Object.defineProperty(obj, "key", {
  configurable: false,
  value: "static"
});
delete obj.name; // true
delete obj.key // false

对象obj有name,key。name可以delete,key则不行。

此外ES5严格模式中delete configuable为false的对象时会直接抛异常。如

复制代码 代码如下:

"use strict";
delete Object.prototype;

FF中控制台报错如下

除了内置对象的一些方法或属性不能删除外,自定义对象也有不能删除的。如delete不能删除对象继承来自原型上的属性

复制代码 代码如下:

function Person() {}
Person.prototype.name = 'John Backus';
var p = new Person();
delete p.name;
console.log(p.name); // 仍然输出 John Backus

如果this和prototype上都有name,那么delete后,会将prototype上的呈现出来
复制代码 代码如下:

function Person() {
    this.name = 'John Backus';
}
Person.prototype.name = 'John Resig';
var p = new Person();
console.log(p.name); // John Backus
delete p.name;
console.log(p.name); // John Resig, 来自原型

如果非要删除原型上的name,只能
复制代码 代码如下:

delete Person.prototype.name

总结下:

1,内置对象的属性及方法多数不能delete(虽然有些能delete,如isNaN、parseInt)

2,对象继承于原型的属性和方法不能delete

原因也很简单,

1,内置对象的属性及方法多数不能delete保护该语言最核心API,这些API被delete了,基本上就废了。如delete Object.prototype。

2,对象继承于原型的属性和方法不能delete是出于保护原型,否则 “类A的对象delete了原型上的属性,那么继承于A的都将丢失该属性”。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn