目录
1.Object.defineproperty方法 的基本配置项
问题1:通过 Object.defineproperty添加的对象的属性不可遍历(不可枚举)。
问题2:解决添加的属性不可遍历后,改变添加的属性的属性值后,但是打印对象,添加的属性值还是没变。
问题3:通过Object.defineproperty给对象添加的属性不可删除,但是直接写的对象属性可以删除。
2. Object.defineproperty方法 的高级配置项 特别重要
虽然没有完全遵循 MVVM 模型,但是 Vue 的设计也受到了它的启发。因此在文档中经常会使用
vm
(ViewModel 的缩写) 这个变量名表示 Vue 实例。上面这句话是Vue2文档里面的,所以我们要学习Vue,就有必要去了解MVVM
Vue实例结果:
分析总结1:
MVVM模型:
1.M:模型(Model):data中的数据
2.V:视图(View) : 模板代码
3.VM:视图模型(ViewModel) :Vue实例
观察发现:
1.data中所有的属性,最后都出现在Vue实例化对象上面
2.Vue实例化对象上所有的属性 及 Vue原型上所有属性,在Vue模板中都可以直接使用。
Object.defineProperty 给对象添加属性的方法。
Object.defineProperty(要添加属性的对象,要添加的属性,{配置项对象})
-
- let person = {
- name:'张三',
- sex:'男',
- age:18
- }
- // Object.defineProperty(person,'age',{
- // value:18,
- // });
- console.log(Object.keys(person)); //添加的属性可以被遍历到
- console.log(person);
-
直接给person对象添加age属性,添加的属性可以被遍历 。
-
- let person = {
- name:'张三',
- sex:'男',
- // age:18
- }
- Object.defineProperty(person,'age',{
- value:18,
- });
- console.log(Object.keys(person));
- console.log(person);
-
通过Object.defineproperty给对象添加的属性打印显示时,添加的属性颜色淡了一点,这个表示该属性不可枚举(不可遍历)
解决办法:配置项enumerable值设为 true
- Object.defineProperty(person,'age',{
- value:18, //配置项1:value:添加属性的值
- enumerable:true,//控制属性是否可以枚举,默认值是false
- });
解决办法:配置项writable值设为 true
- Object.defineProperty(person,'age',{
- value:18, //配置项1:value:添加的属性的值
- enumerable:true,//配置项2:控制属性是否可以枚举,默认值是false
- writable:true, //配置项3:控制属性是否可以被修改,默认值是false
- });
直接写的对象属性:
通过Object.defineProperty添加的对象属性:
解决办法:配置项writable值设为 true
- Object.defineProperty(person,'age',{
- value:18, //配置项1:value:添加的属性的值
- enumerable:true, //配置项2:控制属性是否可以枚举,默认值是false
- writable:true, //配置项3:控制属性是否可以被修改,默认值是false
- configurable:true //控制属性是否可以被删除,默认值是false
- });
-
- let number = 520;
- let person = {
- name:'张三',
- sex:'男',
- }
- Object.defineProperty(person,'age',{
- //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
- get(){
- console.log('有人读取了age属性了');
- return number; //返回的是age属性的值
- },
- //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
- set(newValue){
- console.log('有人修改了age属性,且值是:',newValue);
- }
- });
- console.log(Object.keys(person));
- console.log(person);
-
问题:为什么修改了person.age = 100 ,打印person对象,age属性还是为520 ?
答:因为age属性的值来源于number,number,没改变,set只是收到修改的具体值,但是并没有把number去修改,所以要去修改number的值,才可以。
-
- let number = 520;
- let person = {
- name:'张三',
- sex:'男',
- }
- Object.defineProperty(person,'age',{
- //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
- get(){
- console.log('有人读取了age属性了');
- return number; //返回的是age属性的值
- },
- //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
- set(newValue){
- //newValue收到的是要修改的值
- console.log('有人修改了age属性,且值是:',newValue);
- number = newValue; //要修改number的代码,因为age的值是number的值,set只是收到修改的具体值,但是没有去修改
- }
- });
- console.log(Object.keys(person));
- console.log(person);
-
分析总结2:
number和person对象是两个不同的东西,借助 Object.defineProperty方法让它们产生关联。person确实是一个对象,也确实有age属性,但是age属性的值是现用现取。
-
- let obj = {x:100};
- let obj2 = {y:200};
-
- //通过obj2对象能读到x,也能修改x
- Object.defineProperty(obj2,'x',{
- //读
- get(){
- return obj.x;
- },
- //写
- set(newValue){
- obj.x = newValue;
- }
- })
-
控制台验证:
分析:通过obj可以取操作x,通过obj2也可以去操作x
分析总结2:
vm是Vue的实例化对象。
1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据
3.基本原理(重要)
通过Object.defineProperty()把data对象中所有属性添加到Vue实例化对象vm上。为每一个添加到vm上的属性,都指定一个getter/setter.
在 getter/setter 内部去操作(读/写)data中对应的属性。而data属性值又是被劫持放在_data里面的。
验证: data属性值又是被劫持放在_data里面的
- "app">
- <h2>学校名称:{{name}}h2>
- <h2>学校地址:{{address}}h2>
-
- <script>
- let data = {
- name:'三院',
- address:'亚洲大陆中国'
- }
- const vm = new Vue({
- el:'#app',
- data:data
- })
- console.log(vm);
- script>
- "app">
- <h2>学校名称:{{name}}h2>
- <h2>学校地址:{{address}}h2>
-
- <script>
- const vm = new Vue({
- el:'#app',
- data:{
- name:'三院',
- address:'亚洲大陆中国'
- }
- })
- console.log(vm);
- script>