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

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

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数组中其中的一个元素:

// 使用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类型的变量:

// chrome 不能删除;火狐可以删除function func(){}console.log( func );console.log( delete func );console.log( func );

登录后复制

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

function func1(a, b){}console.log( func1.length );        // 2console.log( delete func1.length );  // true,删除成功console.log( func1.length );         // 0

登录后复制

删除常用变量:

console.log( delete NaN );      // false,删除失败console.log( delete undefined ); // falseconsole.log( delete Infinity );  // falseconsole.log( delete null );      // true,删除成功

登录后复制

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

function Person(){}Person.prototype.name = "蚊子";console.log( delete Person.prototype ); // false,无法删除console.log( delete Object.prototype );  // false

登录后复制

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

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中的属性时:

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:

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,可设置一个或多个值)。

如下:

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()来定义,如下:

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了,反之亦然。

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

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)来获取内部属性。

如:

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,则说明是可以被删除的:

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

登录后复制

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

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操作符与内部属性实例详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2776625.html

(0)
上一篇 2025年3月8日 14:54:27
下一篇 2025年3月8日 14:54:33

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 如何理解js中的闭包

    闭包(closure)是javascript的一大难点,也是它的特色。很多高级应用都要依靠闭包来实现。本次的这篇文章主要是和大家分享了如何理解js中的闭包 ,有需要的小伙伴可以看一下 1、变量作用域 要理解闭包,首先要理解javascrip…

    编程技术 2025年3月8日
    200
  • Angular开发实践之服务端渲染_AngularJS

    这篇文章主要介绍了angular开发实践之服务端渲染,内容还是挺不错的,现在分享给大家,也给大家做个参考。一起过来看看吧 Angular Universal Angular在服务端渲染方面提供一套前后端同构解决方案,它就是Angular U…

    2025年3月8日 编程技术
    200
  • Vue中computed与methods的区别详解_vue.js

    这篇文章主要介绍了vue中computed与methods的区别详解,内容还是觉得挺不错的,现在分享给大家,也给大家做个参考。一起过来看看吧 Vue中computed可以用来简单的拼接需要展示的数据 computed and methods…

    2025年3月8日
    200
  • 使用Vue构建可重用的分页组件

    分页组件在web项目中是十分常见的组件,让我们使用vue构建可重用的分页组件,关于基本结构和相关事件监听大家参考下本文 Web应用程序中资源分页不仅对性能很有帮助,而且从用户体验的角度来说也是非常有用的。在这篇文章中,将了解如何使用Vue创…

    2025年3月8日 编程技术
    200
  • 五种JavaScript常见函数总结

    在 JavaScript 中有一些问题会被拿出来经常讨论,这些问题每个人都有不同的思路,想要理解这些问题,最好的方法就是自己实现一遍,话不多说,开始正题。本篇文章给大家分享的是 五种JavaScript常见函数总结,内容挺不错的,希望可以帮…

    编程技术 2025年3月8日
    200
  • js自执行函数

    这次的这篇文章向大家分享的内容是js自执行函数 ,有需要的朋友可以参考一下 1 用自执行函数来包装代码格式 APP = function(){     var a,b; //变量a、b外部不可见     return {          …

    编程技术 2025年3月8日
    200
  • js 的引用类型

    这次的这篇文章向大家分享的内容是关于js的引用类型,有需要的朋友们可以看一下 引用类型的值(对象)是引用类型的一个实例,,在js 里引用类型是一种数据结构,通常被称为类,es6貌似加了类这个概念, 1:object是一个基础类,其他所有类型…

    编程技术 2025年3月8日
    200
  • 2017、2018年JS面试题记录分享

    这次的这篇文章给大家带来的内容是2017、2018年JS面试题记录分享,有感兴趣的小伙伴可以看一下 推荐相关文章:2020年最全js面试题整理(最新) 2017面试分享(js面试题记录) 1. 最简单的一道题     ’11’ * 2   …

    2025年3月8日
    200
  • js 开发跨平台界面程序

    HTML + CSS + JS 做页面布局等样式控制有种与身俱来的优越感,于是 NodeJS 的世界里便产生了  Node-Webkit(已更名为 NW.js) 和 Atom Shell,它们各自的代表作有 LightTable 和堪与 S…

    编程技术 2025年3月8日
    200
  • JavaScript设计模式系列一:工厂模式

    本篇文章给大家分享的是javascript设计模式系列:工厂模式,有感兴趣的朋友可以看一下 设计模式 设计模式(design pattern)概念:是一套反复使用、思想成熟、经过分类和无数实战设计经验的总结。是为了代码可重用、可扩展、可解耦…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论