文章目录
- 回顾Object.defineProperty方法
- 数据属性
- value
- enumerable
- writable
- configurable
- 访问器属性
- get()
- set(v: any)
- 何为数据代理
- Vue中的数据代理
Vue学习目录
上一篇:(六)Vue之MVVC
回顾Object.defineProperty方法
Object.defineProperty方法的作用是:向对象添加特性,或修改现有特性的属性。
源码:
declare type PropertyKey = string | number | symbol;
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
defineProperty<T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): T;
defineProperty有三个参数,分别是
- 第一个参数o:类型为对象,要在其上添加或修改属性的对象。这可以是JavaScript对象(即用户定义的对象或内置对象)或DOM对象。
- 第二个参数PropertyKey:属性名称。可以是字符串或数字或symbol类型。
- 第三个参数: 属性描述。它可以用于数据属性或访问器属性。
数据属性
- value:设置属性的值
- enumerable:控制属性是否可以枚举(遍历),默认值是false
- writable:控制属性是否可以被修改,默认值是false
- configurable:控制属性是否可以被删除,默认值是false
value
设置属性的值
let person = {
name:'张三',
sex:'男'
}
Object.defineProperty(person,'age',{
value:18
})
console.log(person)
enumerable
控制属性是否可以枚举(遍历),默认值是false
上面程序进行遍历:遍历不出age属性
加个enumerable属性配置:
Object.defineProperty(person,'age',{
value:18,
enumerable:true
})
遍历出age属性
writable
控制属性是否可以被修改,默认值是false
上面程序,修改age值:修改后,person的值还是原来值
加个writable属性配置
Object.defineProperty(person,'age',{
value:18,
enumerable:true,
writable:true
})
可以修改age属性了:
configurable
控制属性是否可以被删除,默认值是false
上面程序,删除age值:删除失败
加个configurable属性配置:
Object.defineProperty(person,'age',{
value:18,
enumerable:true,
writable:true,
configurable:true
})
删除成功:
访问器属性
- get():是一个函数,当有人访问属性时,get(getter)函数就会被调用,且返回值就是属性的值。
- set(v: any):是一个函数,当有人修改属性时,set(setter)函数就会被调用,且会收到修改的具体值
get()
当有人访问属性时,get(getter)函数就会被调用,且返回值就是属性的值。
let number = 18
let person = {
name:'张三',
sex:'男'
}
Object.defineProperty(person,'age',{
get:function(){
console.log('get被调用')
return number
}
})
不去访问age属性时:
点开person,发现有age属性,但是值是(…)
当我们点击这(…)时,就会调用get(getter)函数
直接去访问age属性时也是一样:
set(v: any)
当有人修改属性时,set(setter)函数就会被调用,且会收到修改的具体值
let number = 18
let person = {
name:'张三',
sex:'男'
}
Object.defineProperty(person,'age',{
get:function(){
console.log('get被调用')
return number
},
//可以简写
set(value){
console.log('set被调用')
number = value
}
})
何为数据代理
数据代理:通过一个对象代理另一个对象中属性的操作(读/写)
例如:
<script type="text/javascript">
let obj1 = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
console.log('get被调用')
return obj1.x
},
set(value) {
console.log('set被调用')
obj1.x = value
}
})
</script>
Vue中的数据代理
通过vm(Vue)对象来代理data对象中属性的操作(读/写)
好处:更加方便的操作data中的数据
基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
<div id="root">
<h1>学校名称:{{name}}</h1>
<h1>学校地址:{{addr}}</h1>
</div>
<script type="text/javascript">
Vue.config.productionTip = false//阻止 vue 在启动时生成生产提示。
const vm = new Vue({
el:'#root',
data:{
name:'一中',
addr:'广州'
}
});
</script>
在Vue最下面还有对应的setter和getter
注意:如果打开_data会发现里面又有setter、getter,这可不是数据代理,而是Vue在里面做了数据劫持(这个以后再说),是为了让数据响应到页面进行展示。