Skip to content

属性描述符

属性描述符是JavaScript对象的属性的详细描述,它定义了如何访问和处理对象的属性

属性描述符在JavaScript中是一个非常重要的概念,它允许开发者对对象的属性进行更精细的控制。属性描述符可以分为两种类型:

  • 数据描述符:包含valuewritableenumerableconfigurable 四个特性。其中:
    • value:设置属性的值,默认为undefined
    • writable:表示属性是否可写。
    • enumerable:表示属性是否可枚举。
    • configurable:表示属性描述符是否可配置。
  • 存取描述符(也称为访问器描述符):除了valuewritable,还包含getset函数,用于自定义属性的读取和写入行为。
    • get函数:当读取属性时触发函数。
    • set函数:当修改属性时触发函数。

getOwnPropertyDescriptor()

用于获取对象属性的描述符。描述符是一个对象,包含属性的值、可写性、可枚举性和可配置性等信息。

js
const obj = {
  name: '张三',
  age: 25
};

// 获取name属性的描述符
const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');

console.log(descriptor);
// 输出:{ value: '张三', writable: true, enumerable: true, configurable: true }

defineProperty()

用于在对象上定义新属性或修改现有属性,并返回该对象。它接受三个参数:对象、属性名和属性描述符。

js
const obj = {
    name: '张三',
    age: 16
}

Object.defineProperty(obj, 'age', {
  configurable: false,
  get () {
    return 18
  },
  // val为修改的值
  set (val) {
    throw new Error('不能修改年龄!')
  }
});

console.log(obj.age); // 输出:18
obj.age = 16         // 报错

ES6 提供了一种新的语法糖,用于定义对象的 gettersetter

js
const obj = {
    // getter
    get name() {
      return this._name;
    },
  
    // setter
    set name(value) {
      this._name = value;
    }
  };
  
obj.name = '张三';     // 触发setter,obj._name = '张三'
console.log(obj.name); // 触发geter,读取obj._name

扩展

freeze()

可以使一个对象被冻结。冻结对象可以防止扩展,并使现有的属性不可写入和不可配置。被冻结的对象不能再被更改:不能添加新的属性,不能移除现有的属性,不能更改它们的可枚举性、可配置性、可写性或值,对象的原型也不能被重新指定。

js
const obj = {
  prop: 42,
};

Object.freeze(obj);

obj.prop = 33;          // 严格模式下报错,非严格模式下静默失效
console.log(obj.prop);  // 42

preventExtensions()

可以防止新属性被添加到对象中(即防止该对象被扩展)。它还可以防止对象的原型被重新指定。

js
const object1 = {};

Object.preventExtensions(object1);

object1.age = 18       // 严格模式下报错,非严格模式下静默失效
console.log(object1);  // {}