美文网首页
对象的属性描述(Property Descriptor)

对象的属性描述(Property Descriptor)

作者: SingleDiego | 来源:发表于2019-05-27 17:44 被阅读0次

    参考文章:

    1. https://juejin.im/post/5b97903de51d450e3d2ca94c
    2. https://www.zhihu.com/question/40648241/answer/135240926




    使用 Object.getOwnPropertyDescriptor 方法获取属性的描述:

    let person = {name: 'tom', age: 16};
    let descriptor = Object.getOwnPropertyDescriptor(person, 'name');
    console.log(descriptor );
    

    结果:

    {
      value: "tom", 
      writable: true, 
      enumerable: true, 
      configurable: true
    }
    

    使用 Object.getOwnPropertyDescriptors 方法获取全部属性的描述:

    let person = {name: 'tom', age: 16};
    let descriptor = Object.getOwnPropertyDescriptors(person);
    console.log(descriptor );
    

    结果:

    {
    age: {value: 16, writable: true, enumerable: true, configurable: true}
    name: {value: "tom", writable: true, enumerable: true, configurable: true}
    }
    




    数据属性(Data Properties)

    • configurable(可配置性)

    可配置性决定是否可以使用 delete 删除属性,以及是否可以修改属性描述符的特性,默认 true

    设置为 false 后无法使用 delete 删除属性,严格模式下直接报错;并且不能使用 defineProperty() 方法来修改属性描述符,但可以用使用 defineProperty() 方法将 writable 的状态从 true 改为 false(只有这一种情况可以修改);var 声明变量时默认为 false

    例子:

    let person = {name: 'tom', age: 16};
    Object.defineProperty(person, 'name', {configurable: false});
    delete person.name;
    console.log(person)
    // {name: "tom", age: 16}
    

    可见 name 属性并未被删除。

    • enumerable(可枚举性)

    可枚举性决定属性是否出现在对象的属性枚举中。

    用户定义的普通属性默认是可枚举的,而原生继承的属性默认是不可枚举的。

    使用 propertyIsEnumerable() 可以判断对象的属性是否可枚举:

    let person = {name: 'tom', age: 16};
    
    person.propertyIsEnumerable('name')
    // true
    

    我们修改一下 name 属性的 enumerable 再看看:

    Object.defineProperty(person, 'name', {enumerable: false})
    
    person.propertyIsEnumerable('name')
    false
    

    具体来说,enumerable 属性会影响到:

    1. fon in 循环是否能遍历到该属性
    2. Object.keys 方法是否能取到该属性
    3. JSON.stringify 方法是否能取到该属性
    • value (属性值)

    属性值包含这个属性的数据值,读取属性值的时候,从这个位置读,写入属性值的时候,把新值保存在这个位置。默认 undefined

    • writable (可写性)

    可写性决定是否可以修改属性的值,默认为 true;设置为 false 后赋值语句会静默失败,严格模式赋值直接报错。

    通过 Object.defineProperty() 方法改变属性 value 的值不会受影响,因为这也意味着在重置 writable 的属性值为 false

    看一个例子,name 属性没有被修改:

    let person = {name: 'tom', age: 16};
    Object.defineProperty(person, 'name', {writable: false})
    person.name = 'john'
    console.log(person)
    // {name: "tom", age: 16}
    




    访问器属性(Accessor Properties)

    访问器属性不包含数据值,它们包含一对儿 gettersetter 函数(不过,这两个函数都不是必需的)。

    在读取访问器属性时,会调用 getter 函数,在写入访问器属性时,又会调用 setter 函数并传入新值。

    例子:

    let person = {name: 'tom', _age: 16};
    
    Object.defineProperty(person, 'age', {
      get: function() {
        return this._age;
      },
      set: function(newValue) {
        this._age = newValue;
      }
    })
    
    person.age = 18;
    console.log(person.age)
    // 18
    

    这里我们为 _age 属性设定了 getset 的访问器属性。

    相关文章

      网友评论

          本文标题:对象的属性描述(Property Descriptor)

          本文链接:https://www.haomeiwen.com/subject/jqnhtctx.html