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施加了一些限制:
- 不能修改
configurable标志。- 不能修改
enumerable标志。- 不能将
writable: false修改为true(反过来则可以)。- 不能修改访问者属性的
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),但不能两者都是。