js---对象描述符

424 阅读3分钟

js---对象描述符

js除了具有value外,还有如下的配置项。

  • writable: 如果为true,则值可以进行修改,否则值只能读取。
  • enumerable: 如果为true,则值可以被遍历出,否则值不能被遍历出。
  • configurable: 如果为ture,则值可以被删除,其他特性可以被修改,否则不可以。

如何查看与修改描述符?

查看描述符

要想查看对象这些描述符有以下方法:

1. Object.getOwnPropertyDescriptor(obj,prop)

获取对象指定属性描述符对象。

let obj = {
   name: '属性值'
 }
 console.log(Object.getOwnPropertyDescriptor(obj, 'name'))
// {
    //  configurable: true
    //  enumerable: true
    //  value: '属性值'
    //  writable: true
// }

2. Object.getOwnPropertyDescriptors(obj)

获取对象所有属性的描述符对象。

let id = Symbol('id')
let obj = {
    name: '属性值',
    age: 55,
    [id]: 'id'
}
 console.dir(Object.getOwnPropertyDescriptors(obj))
// {
  // age: {value:55,writable:true,enumerable:true,configurable: true},
  // name: {value:"属性值",writable:true,enumerable:true,configurable:true},
  // Symbol(id):{value:"id",writable:true,enumerable:true,configurable:true},
// }

修改描述符

要想修改对象这些特性有以下方法:

1.Object.defineProperty(obj,prop,descriptor)

修改对象指定属性的描述符。

let obj = {
    name: '属性值',
    age: 55
}
Object.defineProperty(obj, 'name', { writable: false})
console.log(Object.getOwnPropertyDescriptor(obj, 'name'))
// {value: "属性值", writable: false, enumerable: true, configurable: true}

该方法也可以设置新的属性,如果设置属性时没有设置其他描述符,这些描述符都为fasle。

以常规方式{name:'value'}创建的都为true。

2. Object.defineProperties(obj,props)

修改对象任意个属性的描述符。

 Object.defineProperties(obj, {
      name: {  writable: false },
      age: {  writable: false  }
 })
 console.log(Object.getOwnPropertyDescriptors(obj))
// {
    //  age: {value: 55, writable: false, enumerable: true, configurable: true}
    //  name: {value: "属性值", writable: false, enumerable: true,configurable: true}
    // Symbol(id): {value: "id", writable: true, enumerable: true, configurable: true}
// }

描述符:

writable

用于控制属性是否允许修改。

在非严格模式下,在对不可写的属性等进行写入操作时,不会出现错误。但是操作仍然不会成功。在非严格模式下,违反标志的行为(flag-violating action)只会被默默地忽略掉。只在严格模式下会出现错误。

 let obj = {  name: '属性值',  age: 55 }
 Object.defineProperty(obj, 'name', { writable: false })
 obj.name = '新的值'
  console.log(obj)
  // {name: "属性值", age: 55}

enumerable

用于控制属性是否可以被枚举。

  let obj = {  name: '属性值', age: 55 }
  Object.defineProperty(obj, 'name', {  enumerable: false })
  console.log(Object.keys(obj))
  // ["age"]

configurable

用于控制属性能否被删除以及其他描述符能否修改。

configurable:false是个'单行道'。

当configurable设置为fasle时,对 defineProperty 施加了一些限制:

  1. 不能修改 configurable 标志。
  2. 不能修改 enumerable 标志。
  3. 不能将 writable: false 修改为 true(反过来则可以)。
  4. 不能修改访问者属性的 get/set(但是如果没有可以分配它们)

但是 configurable:false:允许对属性值的修改。

 let obj = { name: '属性值',  age: 55 }
 Object.defineProperty(obj, 'name', {
   configurable: false,
 })
 obj.name = '新值'
 console.log(obj)
 // {name: "新值", age: 55}
 Object.defineProperty(obj, 'name', {
    enumerable: false
  })
 // Uncaught TypeError: Cannot redefine property: name

get/set

对象有两种类型的属性。 一种是数据属性。 另一种就是访问器属性。

访问器属性本质上是用于获取和设置值的函数,但从外部代码来看就像常规属性。

 let obj = {
       age: 25,
       get newVal() {
           return this.age
       },
       set newVal(val) {
            this.age = val
       }
 }
  console.log(obj.newVal) // 25
  obj.newVal = 98
  console.log(obj.age)    // 98

当读取obj.newVal时,getter起作用。

当obj.newVal被赋值时,setter起作用。

相比较于数据属性的描述符

Object.getOwnPropertyDescriptor(obj,'newVal')
//{  
  // configurable: true
  // enumerable: true
  // get: ƒ newVal()
  // set: ƒ newVal(val)
//}

由此可知:访问器属性的描述符没有value和writable。但是有get和set函数。

  • get : 一个无参函数, 读取属性时工作。
  • set : 一个有参函数 ,设置属性时工作。
  • configurable: 如果为ture,则值可以被删除,其他特性可以被修改,否则不可以。
  • enumerable: 如果为true,则值可以被遍历出,否则值不能被遍历出。

一个属性要么是访问器(具有 get/set 方法),要么是数据属性(具有 value),但不能两者都是。