语法
Object.defineProperty(obj, prop, descriptor)
Object.defineProperty()方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性并返回这个对象。 这个方法需要三个参数(obj,prop,descriptor)
参数
- obj 对象 -> 给哪个对象加
- prop 属性名 -> 要加的属性的名字 [类型:string]
- descriptor 属性描述 -> 加的这个属性有什么样的特性 [类型:Object]
descriptor中的数据描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值是可写可不写的。存取描述符是有getter函数和setter函数所描述的属性。数据描述符和存取描述符不能同时使用。
- configurable:仅当该属性的configurable为true时,该属性才能够被改变,也能被删除。默认为false
- enumerable:仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为false
- value:该属性对应的值。可以是任何有效的JavaScript值(数值、对象、函数等)。默认是undefined
- writable:仅当该属性的writable为true时,该属性才能被赋值运算符改变,默认是false
- get:一个给属性提供getter方法,如果没有getter则为undefined。该方法返回值被用作属性值,默认undefined
- set:一个给属性提供setter方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认是undefined
1、configurable
configurable特性表示对象的属性是否可以被删除,以及除value和writable特性以外的其它特性是否可以被修改。当configurable为false时,其他属性不管有没有写出来(有默认值),都无法被重新定义或修改。
const user = {
name:'a'
}
Object.defineProperty(user,'name',{
configurable:false
})
console.log(user.name) //{name:'a'}
delete user.name;
console.log(user.name) //{name:'a'}
Object.defineProperty(user,'name',{
configurable:true
})
console.log(user.name) //{name:'a'}
delete user.name
console.log(user.name) //{ }
Object.defineProperty(user,'name',{
get() {
return b
},
configurable:false
})
console.log(user.name) //{name:'b'}
delete user.name
console.log(user.name) //{name:'b'}
Object.defineProperty(user,'name',{
get() {
return b
}
})
console.log(user.name) //throws a TypeError
通过这个属性设置好configurable属性,就不能把user里的name删除了。如果configurable属性为true,则不会抛出任何错误,并且该属性最后会被删除。
2、writable
Object.defineProperty(user,'name',{
value:'b',
writable:false
})
console.log(user.name) //b
user.name = 'c'
console.log(user.name) //b
通过这个属性设置只读,就不能修改user里的name值了
3、value
Object.defineProperty(user,'name',{
value:'hhh'
})
console.log(user.name) //hhh
//添加多个属性值和默认值
const obj = {}
obj.age = 10
//等同于
Object.defineProperty(obj,'age',{
value:10,
writable:true,
configurable:true,
enumerable:true
})
Object.defineProperty(obj,'age',{value:10});
//等同于
Object.defineProperty(obj,'age',{
value:10,
writable:false,
cofigurable:false,
enumerable:false
})
通过这个属性给user里的name赋值
4、enumerable
enumerable定义的属性可以在Object.keys()中被枚举。
const user = {
name:'a',
age:15
}
Object.defineProperty(user,'sex',{
vale:'男',
enumerable:true
})
user.propertyInsEnumerable('sex') // true
Object.keys(user) //['name','age','sex']
console.log(user) //{name:'a',age:15,sex:'男'}
user.time = '2022' //如果使用直接赋值的方法创建对象的属性,则enumerable为true
Object.defineProperty(user,'sex',{
vale:'男',
enumerable:false
})
user.propertyInsEnumerable('sex') //false
Object.keys(user) //['name','age']
console.log(user) //{name:'a',age:15}
通过这个属性决定user里的sex是否能枚举
5、get
get是获取值的时候触发,类型为function,获取值的时候会被调用,不设置是undefined
const user = {
name:'a'
}
const count = 10
Object.defineProperty(user,'age',{
get:function(){
return count;
}
})
console.log(user.age); //10
6、set
set是设置值的时候触发,类型是function,设置值的时候会被调用,不设置是undefined
const user = {
name:'a'
}
const count= 10;
Object.defineProperty(user,'age',{
get:function(){
return count;
console.log('获取值')
},
set:function(val){
console.log('设置值')
return val+1
}
})
console.log(user.age) //10 //获取值
user.age = 100;
console.log(user.age) //设置值 //获取值 //101