vue实现响应式其实是通过Object.defineProperty来实现的。
Object.defineProperty是给一个对象添加属性的。这个方法传三个参数
第一个参数:要给那个对象添加属性
第二个参数:要添加的属性名
第三个参数:配置项,
举个例子:
let person = {
name:'张三',
sex:'男',
}
Object.defineProperty(person,'age',{
value:18
})
console.log(person)
效果:
我们可以看到通过Object.defineProperty来添加的age属性的颜色有所不同。它代表着age不可被枚举。
枚举可以理解为不参与遍历。
我们来试验一下:
利用Object.keys(),传入一个对象,这个方法可以把传入对象所有的属性名,提取出来,变成一个数组。 或者用for in也行。
代码:
let person = {
name:'张三',
sex:'男',
};
Object.defineProperty(person,'age',{
value:18
});
console.log(person);
for (let item in person){
console.log(person[item])
}
console.log(Object.keys(person))
效果图:
我们可以发现,age并没有参与枚举。
这时候如果我们想要让age数据参与枚举,需要用到一个enumerable的属性,它翻译过来也就是可枚举的意思。enumerable:true,控制属性值可枚举。默认值是false。
代码:
Object.defineProperty(person,'age',{
value:18,
enumerable:true
});
效果:
接下来我们来讲一下,通过Object.defineProperty添加的属性,是不能直接对属性进行修改。
如图:
这时候我们需要通过writable的属性,writable就是可以被修改的意思。它的作用就是控制属性可以被修改。默认值是false。
代码:
Object.defineProperty(person,'age',{
value:18,
enumerable:true,//控制属性是否可以枚举,默认值是false
writable:true,//控制属性是否可被修改,默认值是false
});
效果:
我们可以看到通过添加writable属性后,我们已经对age的值进行了修改。
接下来我们再来讲一下删除,要相对Object.defineProperty添加的属性进行删除,需要用到configurable属性,configurable就是可以配置的意思,默认值为false,他的作用就是控制属性是否可以被删除。
代码:
Object.defineProperty(person,'age',{
value:18,
enumerable:true,//控制属性是否可以枚举,默认值是false
writable:true,//控制属性是否可被修改,默认值是false
configurable:true,//控制属性是否可以被删除,默认值为false
});
效果:
讲完了三个属性,接下来讲一下get和set这两个方法
首先我们先来看下代码:
let number = 19;
let person = {
name:'张三',
sex:'男',
age:number
};
console.log(person);
person里面的age属性,是根据number来决定的。但是当代码执行完,我们修改number的值,person里面的age并不会发生改变。
如图:
这时候我们就需要讲到到get以及set了。
get是当读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
废话不多说,上代码:
Object.defineProperty(person,'age',{
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get(){
console.log('您读取了age属性值')
return number
},
});
效果:
可以看到,age值并没有出现。刚才我们介绍了,当我们读取的时候,才会调用。
如图:
图上可看出,点击三个小点,以及person都触发了get方法。numner的值进行了修改,但只要访问的时候,触发了get方法,就会把最新的number值赋值给age。
接下来来讲一下set方法。当修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体的值
代码:
Object.defineProperty(person,'age',{
//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get(){
console.log('您读取了age属性值')
return number
},
//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体的值
set(value){
console.log('您修改了age属性值,值是',value);
number = value
}
});
效果:
可以看到,当age里面的值进行修改,触发了set方法。把修改的值赋值给了number。
以上就是Object.defineProperty的基本使用。