object.defineProperty()的用法就是直接在一个对象上定义一个新属性或修改一个属性。它里面有三个值。1.objj需要定义属性的当前对象2.prop当前需要定义的属性名3.desc属性描述符。
object.defineProperty(obj,prop,desc)
说说这样的方法和普通的添加属性有什么不同。正常添加属性,我们可以直接在animal对象中添加,为什么我们要多次一举要使用Object.defineProperty()方法呢?我们对比两者方法的不同,对此我使用了keys方法。
<script type="text/javascript">
let animal = {
name : "狮子",
age : "3",
}
Object.defineProperty(animal,'sex',{
value:"男"
})
console.log(Object.keys(animal))
</script>
<script type="text/javascript">
let animal = {
name : "狮子",
age : "3",
//普通添加
sex:"男",
}
// Object.defineProperty(animal,'sex',{
// value:"男"
// })
console.log(Object.keys(animal))
</script>
我们看看结果。这是使用objec.defineProperty()方法 ,通过keys来实现,可以看到在进行枚举的时候没有sex,长度也是2。
我们看看结果。这是直接给对象添加的属性 ,通过keys来实现,可以看到在进行枚举的时候有sex。
所以我们得到结果,使用object.defineProperty()方法不可枚举,但是直接给对象添加属性可以直接枚举。
我要是想让他枚举呢?那我们可以在defineProprety()中使用一个属性。
Object.defineProperty(animal,'sex',{
value:"男",
// 让sex可以参加枚举,默认是关闭的
enumerable:true
})
我们再来看一个,我想要在控制台中修改animal的sex属性。当前sex的值在defineProperty中定义的。无法修改。
在普通对象中的sex时。sex的值明显可以直接更改
对此,大家会问,有能给defineProperty方法修改枚举的属性,是不是也有给sex可以修改的属性呢?在这里我介绍的是writable 属性,它能直接让sex变为可修改的。
Object.defineProperty(animal,'sex',{
value:"男",
// 让sex可以参加枚举,默认是关闭的
enumerable:true,
// 让sex变为可修改的
writable:true
})
最后介绍一个属性configurable,在defineProperty中让sex变为可删除的。在普通对象中的属性是可以直接删除的,但是在没有设置了可删除属性的defineProperty方法中,不可删除。
在defineProperty的方法中。
在直接添加属性sex的对象中。
设置可删除的属性。在defineProperty中直接删除。
Object.defineProperty(animal,'sex',{
value:"男",
// 让sex可以参加枚举,默认是关闭的
enumerable:true,
// 让sex变为可修改的
writable:true,
// 让sex变为可删除的
configurable:true
})
接下来说说 (读取)getter和(修改)setter。getter是读取sex后会返回一个值,他不能与value同时存在。
<script type="text/javascript">
let animal = {
name : "狮子",
age : "3",
//普通添加
// sex:'男'
}
Object.defineProperty(animal,'sex',{
// value:"男",
// 让sex可以参加枚举,默认是关闭的
// enumerable:true,
// // 让sex变为可修改的
// writable:true,
// // 让sex变为可删除的
// configurable:true,
// 当我们使用getter函数时,读取sex后返回一个值。
get() {
return 'hah'
}
})
console.log(Object.keys(animal))
</script>
返回的值是hah,可以看到animal中的sex的颜色比较淡,点开括号后,先执行的是‘返回的值’,随后是hah。倒数第二行代码是,读取sex的属性,用的是get()函数。
setter是用来修改读取的值。
<script type="text/javascript">
let gender = '男'
let animal = {
name : "狮子",
age : "3",
//普通添加
// sex:'男'
}
Object.defineProperty(animal,'sex',{
// value:"男",
// 让sex可以参加枚举,默认是关闭的
// enumerable:true,
// // 让sex变为可修改的
// writable:true,
// // 让sex变为可删除的
// configurable:true,
// 当我们使用getter函数时,读取sex后返回一个值。
get() {
console.log('返回的值')
return gender
},
// 使用setter,可以修改读取的值
set(value) {
console.log('我修改了sex,并且把它给了gender')
gender = value
}
})
console.log(Object.keys(animal))
</script>
通过getter和setter,我们用来读取和修改。我们再外部定义一个属性,通过getter读取到sex并返回gender的值,然后通过setter来进行对值的修改。这种方式会更加的灵敏,让我们做到当sex或者gender的值更改的时候,animal会自动的更新里面的值。
总结:我们可以看到有两个不同的对象,通过Object.defineProperty()方法来将他们链接在一起,可以被读取和修改。修改gender就是修改sex,同理,读取sex也是读取gender。