对象的属性描述(Property Descriptor)

参考文章:

  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 的访问器属性。

猜你喜欢

转载自blog.csdn.net/weixin_33753845/article/details/90801855
今日推荐