Skip to content

🔍 属性描述符

📖 概述

​ ES5规范引入了属性描述符Property Descriptor这一概念,它本质上是一个对象,用于描述对象属性的特性,且每个对象属性都关联一个描述符对象。

​ 那对于以传统声明方式定义的属性,其关联的属性描述符对象默认具有哪些特性呢?例如,通过以下方式定义了一个对象,它拥有一个name属性和一个age属性。

javascript
const person = {
    name : 'FatGod',
    age: 18
}

​ 在ES5规范中,怎么获取一个对象属性的描述符对象呢?可以使用规范提供的Object.getOwnPropertyDescriptor方法来进行获取,该方法的具体用法将在下面讲述。下图为name属性所对应的描述符对象。

==???????????????????????????????????????????????==

​ 属性描述符有两种主要类型,分别为数据描述符访问器描述符。数据描述符用于表示属性的值以及值是否可写,访问器描述符用于表示属性将如何被读取和写入。描述符只能是这两种类型之一,不能同时为两者。尽管数据描述符和访问器描述符在特性表现上有所差异,它们依然共享一些基本的属性特性。

👥 公共特性

configurable

configurable为可配置性,当该特性设置为false时,对应属性将受到如下限制。

  1. 该属性不可被删除。在JS严格模式下,当试图删除该属性时,将会抛出一个TypeError错误。
  2. 属性描述符不能在数据类型和访问器类型之间切换。
  3. 属性描述符的特性将不能被更改,当试图更改不可配置属性的描述符特性时,将会抛出一个TypeError错误(⭐️⭐️⭐️但是,若它是一个可写的数据描述符,则value特性依旧可以被更改,writable特性依旧可以更改为false)。

enumerable

enumerable为可枚举性,当该特性设置为false时,对应属性将受到如下限制。

  1. 属性不被Object.assign或展开运算符...所考虑。
  2. 对于非Symbol属性,不能够通过for...in循环、Object.keysObject.values方式进行枚举。

📊 数据描述符特性

value

value为与属性相关联的值,可以是任何有效的JavaScript值,如数字、字符串、对象、函数等。

writable

writable为可写性,当该特性设置为false时,对应属性的值将不可以使用赋值运算符更改。⭐️⭐️⭐️需要注意的是,此时属性是可配置的(configurabletrue),那么依旧可以通过设置属性描述符的value特性来更改属性值。

​ 在JS严格模式下,当试图通过赋值运算符来更改不可写属性的值时,将会抛出一个TypeError错误。

🕵️‍♂️ 访问器描述符特性

get

get为getter函数,当访问对应属性时,该getter函数会被无参调用,且函数的返回值会作为属性读取的值。因此,当属性的描述符是访问器类型,且该特性设置为undefined(未设置)时,对应属性读取的值将永远为undefined

set

set为setter函数,当对应属性被赋值时,该setter函数会被调用,且携带一个参数,即要赋给属性的值。因此,当属性的描述符是访问器类型,且该特性设置为undefined(未设置)时,对应属性的赋值将永远被忽略。


🔌 API

用法就是要用TypeScript表示

获取

  1. Object.getOwnPropertyDescriptor: 返回指定对象属性的描述符对象,若获取不到,则返回undefine

tip: 只能获取指定对象自我属性的属性描述符。

  1. Object.getOwnPropertyDescriptors: 返回一个包含指定对象的所有自我属性描述符的对象,键为属性名,值为对应的属性描述符对象。

定义修改

​ 当通过以上两个获取API得到的属性描述符对象虽然是可变的,但对其进行更改,并不会影响原始属性的配置与特性。ES5中提供了以下两个API来定义或修改对象属性的描述符。

  1. Object.defineProperty: 向指定对象添加一个属性,或修改现有属性的特性,并返回该对象。

  2. Object.defineProperties: 向指定对象添加一个或多个属性,或修改现有属性的特性,并返回该对象。

上次更新于: