首页 > web前端 > js教程 > js中delete操作符与内部属性实例详解

js中delete操作符与内部属性实例详解

小云云
发布: 2018-03-31 17:20:13
原创
2287 人浏览过

本文主要和大家分享js中delete操作符与内部属性实例详解,在讲解Configurable之前,我们首先来看一道面试题:

1

2

3

4

5

6

a = 1;console.log( window.a );

// 1console.log( delete window.a );

// trueconsole.log( window.a );

// undefinedvar b = 2;console.log( window.b );

// 2console.log( delete window.b );

// falseconsole.log( window.b ); // 2

登录后复制

从上面的这道题可以看出两个的区别:在没有使用var声明变量时,使用delete关键词是可以进行删除的,再次获取时值就是undefined了;在使用var声明的变量,使用delete是不能删除的,再获取时值依然是2。

1. delete操作符

使用delete删除变量或属性时,删除成功返回true,否则返回false。如上面的例子中,delete无法删除变量a时,则返回false;而delete能成功删除变量b,则返回true。

除了上述的两种情况,还有其他的各种常用变量也有能被delete删除的,也有不能被删除的。我们先不管delete这些变量时,为什么会产生这样的结果,这里只看他的返回值:

删除delete数组中其中的一个元素:

1

2

3

4

5

// 使用for~in是循环不到的,直接忽略到该元素

// 使用for()可以得到该元素,但是值是undefinedvar arr = [1, 2, 3, 4];console.log( arr );            

// [1, 2, 3, 4]console.log( delete arr[2] );  

// true,删除成功console.log( arr );            

// [1, 2, undefined, 4]

登录后复制

删除function类型的变量:

1

2

3

4

// chrome 不能删除;火狐可以删除function func(){

}

console.log( func );console.log( delete func );

console.log( func );

登录后复制

删除function.length,该length是获取形参的个数:

1

2

3

4

5

function func1(a, b){

}console.log( func1.length );      

 // 2console.log( delete func1.length );

 // true,删除成功console.log( func1.length );      

  // 0

登录后复制

删除常用变量:

1

2

3

4

5

console.log( delete NaN );    

 // false,删除失败console.log( delete undefined );

 // falseconsole.log( delete Infinity );

 // falseconsole.log( delete null );    

 // true,删除成功

登录后复制

删除prototype,而不是删除prototype上的属性:

1

2

3

4

5

function Person(){

}

Person.prototype.name = "蚊子";console.log( delete Person.prototype );

 // false,无法删除console.log( delete Object.prototype );

 // false

登录后复制

删除数组和字符串的length时:

1

2

3

4

5

6

7

var arr = [1, 2, 3, 4];console.log( arr.length );         

// 4console.log( delete arr.length );  

// false,删除失败console.log( arr.length );         

// 4var str = 'abcdefg';console.log( str.length );        

 // 7console.log( delete str.length );  

 // false,删除失败console.log( str.length );        

  // 7

登录后复制

删除obj中的属性时:

1

2

3

4

5

var obj = {name:'wenzi', age:25};console.log( obj.name );      

 // wenziconsole.log( delete obj.name );

 // true,删除成功console.log( obj.name );       

 // undefinedconsole.log( obj );            

 // { age:25 }

登录后复制

删除实例对象中的属性时,从以下的输出结果可以看出,使用delete删除属性时,删除的仅仅是实例对象本身的属性,而不能删除prototype上的属性,即使再删一次也是删除掉不的;若要删除prototype上的属性的属性或方法,只能是:delete Person.prototype.name:

1

2

3

4

5

6

7

8

9

10

function Person(){    this.name = 'wenzi';

}

Person.prototype.name = '蚊子';var student = new Person();console.log( student.name );       

// wenziconsole.log( delete student.name );

// true,删除成功console.log( student.name );       

// 蚊子console.log( delete student.name );

// trueconsole.log( student.name );      

 // 蚊子console.log( delete Person.prototype.name );

 // true,删除成功console.log( student.name );      

  // undefined

登录后复制

2. js的内部属性

在上面的例子中,有的变量或属性能够删除成功,而有的变量或属性则无法进行删除,那是什么决定这个变量或属性能不能被删除呢。

ECMA-262第5版定义了JS对象属性中特征(用于JS引擎,外部无法直接访问)。ECMAScript中有两种属性:数据属性和访问器属性。

2.1 数据属性

数据属性指包含一个数据值的位置,可在该位置读取或写入值,该属性有4个供述其行为的特性:

. [[configurable]]:表示能否使用delete操作符删除从而重新定义,或能否修改为访问器属性。默认为true;
. [[Enumberable]]:表示是否可通过for-in循环返回属性。默认true;
. [[Writable]]:表示是否可修改属性的值。默认true;
. [[Value]]:包含该属性的数据值。读取/写入都是该值。默认为undefined;如上面实例对象Person中定义了name属性,其值为’wenzi’,对该值的修改都反正在这个位置

要修改对象属性的默认特征(默认都为true),可调用Object.defineProperty()方法,它接收三个参数:属性所在对象,属性名和一个描述符对象(必须是:configurable、enumberable、writable和value,可设置一个或多个值)。

如下:

1

2

3

4

var person = {};Object.defineProperty(person, 'name', {

    configurable: false,    // 不可删除,且不能修改为访问器属性

    writable: false,        // 不可修改

    value: 'wenzi'          // name的值为wenzi});console.log( person.name);          // wenziconsole.log( delete person.name );  // false,无法删除person.name = 'lily';console.log( person.name );         // wenzi

登录后复制

可以看出,delete及重置person.name的值都没有生效,这就是因为调用defineProperty函数修改了对象属性的特征;值得注意的是一旦将configurable设置为false,则无法再使用defineProperty将其修改为true(执行会报错:Uncaught TypeError: Cannot redefine property: name);

2.2 访问器属性

它主要包括一对getter和setter函数,在读取访问器属性时,会调用getter返回有效值;写入访问器属性时,调用setter,写入新值;该属性有以下4个特征:

. [[Configurable]]:是否可通过delete操作符删除重新定义属性;
. [[Numberable]]:是否可通过for-in循环查找该属性;
. [[Get]]:读取属性时自动调用,默认:undefined;
. [[Set]]:写入属性时自动调用,默认:undefined;

访问器属性不能直接定义,必须使用defineProperty()来定义,如下:

1

2

3

4

5

6

7

8

var person = {

    _age: 18};Object.defineProperty(person, 'isAdult', {

    Configurable : false,

    get: function () {        if (this._age >= 18) {            return true;

        } else {            return false;

        }

    }

});console.log( person.isAdult );  // true

登录后复制

不过还是有一点需要额外注意一下,Object.defineProperty()方法设置属性时,不能同时声明访问器属性(set和get)和数据属性(writable或者value)。意思就是,某个属性设置了writable或者value属性,那么这个属性就不能声明get和set了,反之亦然。

如若像下面的方式进行定义,访问器属性和数据属性同时存在:

1

2

3

4

5

6

7

8

var o = {};Object.defineProperty(o, 'name', {

    value: 'wenzi',

    set: function(name) {

        myName = name;

    },

    get: function() {        return myName;

    }

});

登录后复制

上面的代码看起来貌似是没有什么问题,但是真正执行时会报错,报错如下:

Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value

对于数据属性,可以取得:configurable,enumberable,writable和value;

对于访问器属性,可以取得:configurable,enumberable,get和set。

由此我们可知:一个变量或属性是否可以被删除,是由其内部属性Configurable进行控制的,若Configurable为true,则该变量或属性可以被删除,否则不能被删除。

可是我们应该怎么获取这个Configurable值呢,总不能用delete试试能不能删除吧。有办法滴!!

2.3 获取内部属性

ES5为我们提供了Object.getOwnPropertyDescriptor(object, property)来获取内部属性。

如:

1

var person = {name:'wenzi'};var desp = Object.getOwnPropertyDescriptor(person, 'name'); // person中的name属性console.log( desp );    // {value: "wenzi", writable: true, enumerable: true, configurable: true}

登录后复制

通过Object.getOwnPropertyDescriptor(object, property)我们能够获取到4个内部属性,configurable控制着变量或属性是否可被删除。这个例子中,person.name的configurable是true,则说明是可以被删除的:

1

2

3

4

console.log( person.name );        

// wenziconsole.log( delete person.name ); 

// true,删除成功console.log( person.name );        

// undefined

登录后复制

我们再回到最开始的那个面试题:

1

a = 1;var desp = Object.getOwnPropertyDescriptor(window, 'a');console.log( desp.configurable );   // true,可以删除var b = 2;var desp = Object.getOwnPropertyDescriptor(window, 'b');console.log( desp.configurable );   // false,不能删除

登录后复制

跟我们使用delete操作删除变量时产生的结果是一样的。

相关推荐:

JavaScript delete操作符应用实例_javascript技巧

以上是js中delete操作符与内部属性实例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

相关标签:
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板