轻松学习 JavaScript(7):对象属性描述符

转载 2018年01月11日 00:00:00

(点击上方公众号,可快速关注)

英文: Dhananjay Kumar   译文:码农网/小峰

http://www.codeceo.com/article/easy-javascript-07-object-property-descriptors.html


在JavaScript中,你可以如下所示创建一个对象字面量:

var cat = {

    name: 'foo',

    age: 9

};


乍一看,好像对象cat有字符串和数字值这两个属性。然而,这不仅仅是JavaScript解释器。在ES5中,介绍了属性描述符的概念。在我们继续讨论属性描述符之前,让我们试着回答几个问题:

  • 如何创建只读属性?

  • 如何制定不可枚举的属性?

  • 如何使属性不可配置?

  • 如何确定一个属性是否是只读的?


如果你理解属性描述符,那么你就可以回答所有这些问题。

请看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

var a = Object.getOwnPropertyDescriptor(cat, 'name');

console.log(a);


输出将如下所示:

正如你在这里看到的,这个属性有四个特征:

value保存属性的数据,而writable,enumerable和configurable则描述属性的其他特征。接下来我们将对这些特征一一阐述。

writable

属性的值是否可以更改是由writable特征决定的。如果writable设置为false,那么属性的值不能更改,JavaScript将忽略属性值中的任何更改。请看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { writable: false });

console.log(cat.name); // foo

cat.name = "koo"; // JavaScript will ignore it as writable is set to false

console.log(cat.name); // foo


你可以使用Object.defineProperty更改writable、enumerable和configurable特征的值。我们稍后会在这篇文章中详细讨论Object.defineProperty,但正如你在上面的代码片段中看到的那样,我们已经将writable属性设置为false,从而改变了name属性的值。JavaScript将忽略重新分配,并且name属性的值将保持为foo。

如果以严格模式运行代码,那么为了重新分配writable设置为false的属性值,JavaScript将抛出异常。请看下面的代码:

'use strict';

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { writable: false });

console.log(cat.name); // foo

cat.name = "koo"; // error


在这里,JavaScript以严格模式运行,因此,当你重新分配name属性的值时,JavaScript将抛出异常,如下所示:

这里的错误消息说,你不能赋值到只读属性。也就是说,如果属性的writable特征设置为false,那么属性将充当只读属性。

configurable

属性的其他特征是否可以配置取决于configurable的值。如果属性configurable设置为false,则不能更改writable和enumerable的值。请看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { configurable: false });

Object.defineProperty(cat, 'name', { enumerable: false });


在这里,我们将name属性的configurable设置为false。之后,我们将enumerable设置为false。如前所述,一旦一个属性的configurable设置为false,那么你就不能改变另一个特征。

对于上面的代码,JavaScript会抛出一个TypeError异常,如下图所示。你会得到无法重新定义属性名称的错误:

在使用configurable的时候,你需要记住,改变configurable的值只能做一次。如果将属性的configurable设置为false,那么你就不能重新分配它;你无法撤消对configurable的更改。请看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { configurable: false });

Object.defineProperty(cat, 'name', { configurable: true });


我们在重新分配name属性的configurable,但是,JavaScript会对上述操作抛出一个TypeError,如下图所示。正如你所看到的,一旦configurable被设置为false,就不能撤销那个更改。


另一个重要的事情是,即使configurable设置为false,writable也可以从true更改为false——但反之则不然。请看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { configurable: false });

Object.defineProperty(cat, 'name', { writable: false });

cat.name = 'koo';

console.log(cat.name); // foo


如果不是在严格模式下,上面的代码不会抛出任何异常。正如我们前面所讨论的,即使configurable为false,writable也可以从true变为false,反之则不然。另一个需要牢记的重要事项是,你无法删除configurable设置为false的属性。

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { configurable: false });

delete cat.name; // wont delete as configurable is false

console.log(cat.name); // foo

delete (cat.age); // will be deleted

console.log(cat.age); // undefined


在上面的代码中,你会发现JavaScript不会删除name属性,因为name属性的configurable设置为false。

enumerable

对于一个属性,如果你设置了enumerable:false,那么这个属性将不会出现在枚举中,因此它不能用在诸如for … in循环这样的语句中。

请看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { enumerable: false });

for (let f in cat) {

    console.log(f); // will print only age

}


在这里,你只能得到age,因为name的enumerable被设置为了false。这是另一个需要记住的重要事项:通过设置enumerable:false,唯一的属性将不可用于枚举。我们来看下面的代码:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { enumerable: false });

console.log(cat.name); // foo

console.log('name' in cat); // true


在这里,name属性enumerable设置为false,但你可以访问它。在检查name是否属于cat的属性时,你也会发现是true。

有时,你可能需要检查某个特定属性enumerable是否设置为false或true。你可以通过使用propertyIsEnumerable方法来做到这一点:

var cat = {

    name: 'foo',

    age: 9

};

Object.defineProperty(cat, 'name', { enumerable: false });

console.log(cat.propertyIsEnumerable("name")); // false


结论

作为一名专业的JavaScript开发人员,你必须对JavaScript对象属性描述符有一个很好的理解,我希望你能从这篇文章中学到一些知识!请继续关注我们的下一篇文章,继续学习JavaScript中更重要的概念。




觉得本文对你有帮助?请分享给更多人

关注「前端大全」,提升前端技能

  • 本文已收录于以下专栏:

JavaScript 属性描述符

原文地址:http://codethoughts.info/javascript/2015/06/16/javascript-property-descriptors/ 什么是属性描述符 ...
  • tianxiawuzhei
  • tianxiawuzhei
  • 2015年09月11日 10:21
  • 1447

Python之美[从菜鸟到高手]--玩转描述符和属性

你知道property的实现原理吗? 你知道@classmethod,@staticmethod的原理吗?如果你摇头了,那么这篇文章你肯定不能错过,让我们开始吧?         在说property...
  • yueguanghaidao
  • yueguanghaidao
  • 2013年08月25日 14:37
  • 11136

滨州学院面向对象软件工程期末复习题

一.面向对象软件工程概述   1.封装是指把对象的(A)结合在一起,组成一个独立的对象。 A.属性和操作 B.信息流 C.消息和事件 D.数据的集合 2.状态图和活动图建立了UML面向对象开发...
  • A_Yan0619
  • A_Yan0619
  • 2016年07月12日 09:04
  • 1921

轻松学习JavaScript二十一:DOM编程学习之获取元素节点的子节点和属性节点

我们这里所说的获取元素节点的所有子节点包含元素子节点和文本节点两种。还是拿上一篇博文的代码实例进行 分析: JS代码位置 window.onl...
  • erlian1992
  • erlian1992
  • 2015年12月18日 21:21
  • 3527

轻松学习 JavaScript——第 4 部分:函数中的 arguments 对象

点击上方“程序员大咖”,选择“置顶公众号” 关键时刻,第一时间送达! JavaScript函数具有像数组一样的对象,这些对象称为arguments,与传递给函数的参数相...
  • Px01Ih8
  • Px01Ih8
  • 2017年12月01日 00:00
  • 42

轻松学习 JavaScript (4):函数中的 arguments 对象

(点击上方公众号,可快速关注) 英文: Dhananjay Kumar   译文:码农网/小峰 http://www.codeceo.com/article/easy-java...
  • VhWfR2u02Q
  • VhWfR2u02Q
  • 2017年11月18日 00:00
  • 112

轻松学习JavaScript十:JavaScript的Date对象制作一个简易钟表

JS提供了Date类型来处理时间和日期。Date类型内置一系列获取和设置日期时间信息的方法。下面我们简单的 概述一下这个Date类型。        大概看了一下Date类型的方法,下面给...
  • qq_15167261
  • qq_15167261
  • 2015年12月04日 09:27
  • 221

轻松学习JavaScript九:JavaScript对象和数组

许多高级编程语言都是面向对象的,比如C++、C#和Java等高级程序设计语言,那么一种面向对象语言有哪些基 本要求呢?下面我们就通宿地说一下面向对象的一些知识。        一种面向对象语言需要向开...
  • erlian1992
  • erlian1992
  • 2015年12月02日 19:43
  • 2033

轻松学习JavaScript十四:JavaScript的RegExp对象(正则表达式)

一RegExp对象概述        RegExp对象表示正则表达式,RegExp是正则表达式的缩写,它是对字符串执行模式匹配的强大工具。RegExp 对象用于规定在文本中检索的内容。当您检索某个文本...
  • erlian1992
  • erlian1992
  • 2015年12月12日 17:04
  • 2013

轻松学习JavaScript十:JavaScript的Date对象制作一个简易钟表

JS提供了Date类型来处理时间和日期。Date类型内置一系列获取和设置日期时间信息的方法。下面我们简单的 概述一下这个Date类型。        大概看了一下Date类型的方法,下面给出: ...
  • erlian1992
  • erlian1992
  • 2015年12月03日 19:08
  • 2800
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:轻松学习 JavaScript(7):对象属性描述符
举报原因:
原因补充:

(最多只允许输入30个字)