属性描述对象

45 阅读2分钟

概述

JavaScript 提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。

{
  value: 123,
  writable: false,
  enumerable: true,
  configurable: false,
  get: undefined,
  set: undefined
}

属性描述对象提供6个元属性。

Object.getOwnPropertyDescriptor()方法可以获取属性描述对象。它的第一个参数是目标对象,第二个参数是一个字符串,对应目标对象的某个属性名。

var obj = { p: 'a' };

Object.getOwnPropertyDescriptor(obj, 'p')
// Object { value: "a",
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

上面代码中,Object.getOwnPropertyDescriptor()方法获取obj.p的属性描述对象。

  • 注意,Object.getOwnPropertyDescriptor()方法只能用于对象自身的属性,不能用于继承的属性。

Object.getOwnPropertyNames()

Object.getOwnPropertyNames方法返回一个数组,成员是参数对象自身的全部属性的属性名,不管该属性是否可遍历。

var obj = Object.defineProperties({}, {
  p1: { value: 1, enumerable: true },
  p2: { value: 2, enumerable: false }
});

Object.getOwnPropertyNames(obj)
// ["p1", "p2"]

上面代码中,obj.p1是可遍历的,obj.p2是不可遍历的。Object.getOwnPropertyNames会将它们都返回。

  • Object.keys只返回对象自身的可遍历属性的全部属性名。

Object.defineProperty()方法允许通过属性描述对象,定义修改一个属性,然后返回修改后的对象,它的用法如下:

Object.defineProperty(object, propertyName, attributesObject)

Object.defineProperty方法接受三个参数,依次如下。

  • object:属性所在的对象
  • propertyName:字符串,表示属性名
  • attributesObject:属性描述对象

如果属性已经存在,Object.defineProperty()方法相当于更新该属性的属性描述对象。

实例对象的propertyIsEnumerable()方法返回一个布尔值,用来判断某个属性是否可遍历。注意,这个方法只能用于判断对象自身的属性,对于继承的属性一律返回false

属性描述对象的各个属性称为“元属性”,因为它们可以看作是控制属性的属性。

具体来说,如果一个属性的enumerablefalse,下面三个操作不会取到该属性。

  • for..in循环
  • Object.keys方法
  • JSON.stringify方法

有时需要冻结对象的读写状态,防止对象被改变。JavaScript 提供了三种冻结方法,最弱的一种是Object.preventExtensions,其次是Object.seal,最强的是Object.freeze