高级前端js【Q550】简述 Object.defineProperty

简述 Object.defineProperty

Issue 欢迎在 Gtihub Issue 中回答此问题: Issue 564

Author 回答者: shfshanyue

与直接为一个对象的属性赋值(o.a = 3)不同,Object.defineProperty 可更为精确,拥有更多选项地为对象属性赋值

属性描述符拥有两种: 数据描述符与存取描述符

数据描述符 (data descriptor)

决定该属性值是否可写

const o = {};
Object.defineProperty(o, "a", {
  configurable: false,
  enumerable: false,
  writable: true,
  value: 3,
});
  • configurable: 是否可被删除
  • enumerable: 是否可被枚举,不可枚举属性无法通过 Object.keys 获取到
  • writable: 是否可更改该属性值
  • value: 该属性值的值

当我们使用赋值运算符为对象添加属性时,实际上是添加了一个数据描述符

> o.c = 5
> Object.getOwnPropertyDescriptor(o, 'c')
< {value: 5, writable: true, enumerable: true, configurable: true}

存取描述符 (accessor descriptor)

可对对象属性进行拦截,Vue2 的数据绑定原理便是基于此

const o = {};
Object.defineProperty(o, "a", {
  configurable: false,
  enumerable: false,
  get() {
    return this._a;
  },
  set(a) {
    this._a = a * 10;
  },
});