对象的2种属性

268 阅读2分钟

笔记来源:zh.javascript.info/object-prop… 两种类型的对象属性:数据属性和访问器属性(accessor properties),后者指 gettersetter

对象属性配置

属性标志

  • 对象属性的标志
    • value,属性的值
    • writable — 如果为 true,则值可以被修改,否则它是只可读的。
    • enumerable — 如果为 true,则会被在循环中列出,否则不会被列出。
    • configurable — 如果为 true,则此特性可以被删除,这些属性也可以被修改,否则不可以。
  • 访问(属性描述符)
    let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
    
  • 修改
    Object.defineProperty(obj, propertyName, descriptor)
    
    let user = {}
    Object.defineProperty(user, "name", {
      vlaue: "djp", // 其他特性未设置,默认为 false
    })
    
    let descritor = Object.getOwnPropertyDescritor(user, 'name')
    /*
    {
      "value": "John",
      "writable": false,
      "enumerable": false,
      "configurable": false
    }
     */
    
  • 只读
    • {writable: false} 严格模式下修改属性值会报错,非严则不会,但依然不会修改值
  • 枚举
    • {enumerable: false} for..inObject.keys() 不能遍历到
  • 不可配置
    • 使属性变成不可配置是一条单行道。我们无法使用 defineProperty 把它改回去。
    • 不能修改 configurable 标志。
    • 不能修改 enumerable 标志。
    • 不能将 writable: false 修改为 true(反过来则可以)。
    • 不能修改访问者属性的 get/set(但是如果没有可以分配它们)。

  • Object.defineProperties
    Object.defineProperties(obj, {
      prop1: descriptor1,
      prop2: descriptor2
      // ...
    });
    
  • Object.getOwnPropertyDescriptors
    let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj));
    
    • for..inObject.keys会忽略 symbol 类型的属性,而该函数不会

属性的 getter 和 setter

两种类型的对象属性:数据属性和访问器属性(accessor properties)

Getter 和 setter

let user = {
  name: "John",
  surname: "Smith",

  get fullName() {
    return `${this.name} ${this.surname}`;
  }
   set fullName(value) {
     [this.name, this.surname] = value.split(" ");
   }
};

alert(user.fullName); // John Smith
  • user.fullName 会调用 getuser.fullName = "A B" 会调用 set 方法

访问器描述符

对于访问器属性,没有 value 和 writable,但是有 get 和 set 函数。

  • get —— 一个没有参数的函数,在读取属性时工作,
  • set —— 带有一个参数的函数,当属性被设置时调用,
  • enumerable —— 与数据属性的相同,
  • configurable —— 与数据属性的相同。
    // 为实例对象设置访问器属性
    function User(name, birthday) {
      this.name = name;
      this.birthday = birthday;
    
      // 年龄是根据当前日期和生日计算得出的
      Object.defineProperty(this, "age", {
        get() {
          let todayYear = new Date().getFullYear();
          return todayYear - this.birthday.getFullYear();
        }
      });
    }
    
      let john = new User("John", new Date(1992, 6, 1));