Object 的属性描述符

描述符key说明反转状态数据描述符,访问器描述符是否可更改描述符类型+删除DontDelete数据描述符属性的值,是否可修改值(赋值)Read-only访问器描述符get set。
摘要由CSDN通过智能技术生成

Object 的属性描述符

在 JavaScript 中, 对象(Object)可以看作是属性(property)的集合,属性是 key:value 的形式。key 可以是字符串也可以是 Symbolvalue可以是任何类型(包括其它对象)。

对象的每个属性(property)都有对应的 attributes(标志),由于 attributes 是在 JavaScript 引擎内部使用的,所以我们并不能直接访问到它们。为了区分两者,通常情况下 [property] 是用单方括号,[[attribute]] 是用双方括号。

有一部分特殊的 attributesproperty 的描述符,我们可以在 Object.defineProperty()方法中直观地看到,此方法允许我们精准地添加或修改对象的属性及其描述符。

Object.defineProperty()

静态方法 Object.defineProperty() 可以在对象上定义新的属性,也可以修改已有的属性,它会返回本对象。

格式:Object.defineProperty(obj, prop, descriptor)

两种描述符

对象中的属性描述符有两种形式:数据描述符访问器描述符数据描述符是具有的属性(可写或不可写),访问器描述符是由一对 getter-setter 函数描述的属性。

data descriptors
accessor descriptors

属性描述符要么是数据描述符,要么是访问器描述符,不能两者兼而有之。

数据描述符访问器描述符都是对象,即 key:value 的集合,它们都有下面的两个 key:

  • enumerable 布尔类型。当且仅当在枚举对象的属性列表时,该属性需要被显示出来的时候,才会被置为 true。
  • configurable 布尔类型。如果可以更改该属性的描述符类型(数据描述符 or 访问器描述符),且可以在对象上删除该属性的时候,就置为 true。

数据描述符还可以有以下 key:

  • value 与属性关联的值,可以是任何有效的 JavaScript 值。
  • writable 布尔类型。如果可以使用赋值运算符来修改该属性的 value,那就置为 true

访问器描述符还可以有以下 key:

  • get 用作属性的 getter 函数,如果没有则为 undefined。当访问该属性的值时,就会调用此函数(不带参数),并将 this 设置为访问该属性的对象,返回值将被用作是该属性的值。
  • set 用作属性的 setter 函数,如果没有则为 undefined。当设置(assign)该属性的值时,就会调用此函数(带一个参数,即分配给属性的值),并将 this 设置为给该属性分配值的对象。
    如果描述符既没有value, writable也没有 get, set,就会将其视为数据描述符。如果描述符既有 value/writable 也有 get/set,则会抛出异常。

注意:这些 attributes 不一定是描述符自身的 properties,也可能是继承来的 properties。所以保险起见,要么使用 Object.create(null) 让描述符指向 null,要么使用对象字面量来显式指定描述符的值。如下:
//todo

// 1. Object.create(null)
let obj = {
   };
let descriptor = Object.create(null); // no inherited properties
descriptor.value = 'static';
Object.defineProperty(obj, 'key1', descriptor);

// 2. 用对象字面量,显式指定
Object.defineProperty(obj, 'key2', {
   
    enumerable: false,
    configurable: false,
    writable: false,
    value: 'static'
});

默认值

Object.defineProperty() 定义的描述符的默认值分别是:

  • enumerable, configurable, writable 均默认是 false
  • value, get, set 均默认是 undefined
    也就是说,通过此方法添加的属性,默认是不可枚举、不可变的。而通过赋值添加的普通属性,默认是可枚举、可删除可修改的。
let person = {
   
    name: "David"
};
person.age = 34;
Object.defineProperty(person, "sex", {
    value: "male" });
console.log(Object.getOwnPropertyDescriptors(person)); // 详见下方截图

以上代码,运行结果如下:


{
   
  name: {
   
    value: 'David',
    writable: true,
    enumerable: true,
    configurable: true
  
  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Spider Cat 蜘蛛猫

你的鼓励将会是我最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值