defineproperty方法用来添加或修改对象的属性,共有三个参数obj(要添加或修改属性的对象名),prop(要添加或修改的属性名),descriptor(要添加或修改属性的配置项)
descriptor可取以下键值:
configurable:true|false 当值为true时属性的配置项才能够被改变,也能被删除,默认为false
enumerable:true|false 当值为true时才能被枚举,默认为false
value:属性对应的值
writable:true|false 当值为true时属性值才能被修改,默认为false
get:访问属性时,该方法会被执行,默认为undefined
set:修改属性值时,该方法会被触发,默认为undefined
该方法添加的属性在对对象进行遍历时是不会进入到迭代器中参加遍历的,也就是说不可枚举,如下所示,添加c后再遍历obj会发现只输出了a与b ,可证明由此方法添加的属性不可枚举。
var obj={
'a':1,
'b':2
}
Object.defineProperty(obj,'c',{
value:3
})
for (var i in obj) {
console.log(i)
}
如何解决上面的问题,只需要在添加或修改属性时在其第三个参数中加入enumerable:true即可
另外,由defineProperty添加的属性也不能进行修改(obj.c=4是不能实现的),那么要如何更改才能使其能修改呢?只需要在第三个参数中加入writable:true即可
get方法
当读取school的room属性时,get函数(getter)就会被调用,且返回值就是room的值。以下方法可以实现对象中的某个属性关联某个变量,当变量值变的时候属性值也可以自动变化。
var num='605'
var school = {
'teacher': 'zs',
'student': 'ls'
}
Object.defineProperty(school, 'room', {
get() {
return num
}
})
因为get的返回值为num,所以当我改变num值再取room的值时,会发现room的值已经改变。
set方法
当修改school的属性时,set函数(setter)会被调用,且会收到修改的具体值
var num = '605'
var school = {
'teacher': 'zs',
'student': 'ls'
}
Object.defineProperty(school, 'room', {
get() {
return num
},
set(val) {
num = val
}
})
当在控制台为school.room赋值时,会调用set方法将值赋给num
什么是数据代理
通过一个对象代理对另一个对象中属性的操作(读/写)
基本原理:
-
通过Object.defineProperty()把data对象中所有属性添加到vm上
-
为每一个vm上的属性,都指定一个getter/setter
-
在getter/setter内部去操作(读/写)data中对应的属性