var obj = {
  a: 2
};
Object.getOwnPropertyDescriptor(obj, "a");
// {
//    value: 2, // 值
//    writable: true, // 可写
//    configurable: true, // 可配置
//    enumerable: true // 可枚举
// }
  1. Writable
    writable 决定是否可以修改属性的值。
    之后我们会介绍 getter 和 setter,不过简单来说,你可以把 writable:false 看作是属性不可改变,相当于你定义了一个空操作 setter。

  2. Configurable
    只要属性是可配置的,就可以使用 defineProperty(..) 方法来修改属性描述符:

    Object.defineProperty(myObject, "a", {
      value: 6,
      writable: true,
      configurable: true,
      enumerable: true
    });

    要注意有一个小小的例外:即便属性是 configurable:false,我们还是可以把 writable 的状态由 true 改为 false,但是无法由 false 改为 true。
    除了无法修改,configurable:false 还会禁止删除这个属性:

    var myObject = {
      a:2
    };
    myObject.a; // 2
    delete myObject.a;
    myObject.a; // undefined
    // 设置为不可配置
    Object.defineProperty(myObject, "a", {
      value: 2,
      writable: true,
      configurable: false,
      enumerable: true
    });
    myObject.a; // 2
    delete myObject.a;
    myObject.a; // 2
  3. Enumerable
    从名字就可以看出,这个描述符控制的是属性是否会出现在对象的属性枚举中,比如说 for..in 循环。如果把 enumerable 设置成 false,这个属性就不会出现在枚举中,虽然仍然可以正常访问它。相对地,设置成 true 就会让它出现在枚举中。