Vue双向绑定原理(二)访问器属性defineProperty()
来源:互联网 发布:淘宝联盟的东西便宜吗 编辑:程序博客网 时间:2024/04/27 01:15
访问器属性的介绍
参考资料:《JavaScript高级程序设计》(第三版)第六章
js的对象有两种属性: 数据属性和访问器属性。
1.数据属性
数据属性包含一个数据值的位置。这个位置可以读取和写入值。数据属性也就是我们最常见的对象属性。数据属性有4个描述他行为的特性:
- Configurable: 能否用delete删除属性从而重新定义属性。默认为true
- Enumerable: 能否通过for-in遍历,即是否可枚举。默认为true
- Writable: 是否能修改属性的值。默认为true
- Value: 包含这个属性的数据值,读写属性的时候其实就在这里读写。默认为undefined
要修改属性的上述4个默认特性,就必须使用ECMAScript的Object.defineProperty()方法,该方法包含3个参数:属性缩在的对象,属性名,描述符对象。描述符对象的属性必须在上述4个属性中。例如:
var person = {};Object.defineProperty(person,"name",{ writable: false, value: "Nicholas"});alert(person.name); // "Nicholas"person.name = "Tom";alert(person.name); // "Nicholas"
上例创建了一个不可写的name属性并赋值。所以无法修改。
注意,一旦把Configurable属性设置为false,就无法再将其变回true了,此时再想修改特性,就都会报错了。
2.访问器属性
访问器属性不包含数据值,他们包含一对getter和setter函数(非必须)。在读写访问器属性的值的时候,会调用相应的getter和setter函数,而我们的vue就是在getter和setter函数中增加了我们需要的操作。
访问器属性有以下4个特性:
- Configurable: 能否用delete删除属性从而重新定义属性。默认true
- Enumerable: 能否通过for-in遍历,即是否可枚举。默认true
- get: 读取属性时调用的函数,默认undefined
- set: 写入属性时调用的函数,默认undefined
var book = { _year: 2004, edition: 1};Object.defineProperty(book,"year",{ get: function(){ return this._year; }, set: function(newValue){ if(newValue>2004){ this.year= newValue; this.edition += new Value-2004; } }});book.year = 2005;alert(book.edition); //2
上例创建了一个book对象,并定义了两个默认属性 _year 和 edition 。_year前边的下划线表示只能通过对象方法访问的属性。而访问器属性year则包含getter和setter函数。修改year属性,会导致_year和edition改变。这就是访问器属性的常用方式,即设置一个属性值会导致其他属性发生变化。
当然,不一定非要同时制定getter和setter,只有getter则不能写,只有setter则不能读。
在Vue中的作用
Vue会遍历实例的data属性,把每一个data都设置为访问器,然后在该属性的getter函数中将其设为watcher,在setter中向其他watcher发布改变的消息。这样,配合发布/订阅模式,改变其中的一个值,会发布消息,所有的watcher会更新自己,这些watcher也就是绑定在dom中的显示信息,比如 v-text=”year” 和 {{ year }} 这些节点。从而达到改变浏dom,在浏览器中实时变化的效果,代码如下:
//遍历传入实例的data对象的属性,将其设置为Vue对象的访问器属性 function observe(obj,vm){ Object.keys(obj).forEach(function(key){ defineReactive(vm,key,obj[key]); }); } //设置为访问器属性,并在其getter和setter函数中,使用订阅发布模式。互相监听。 function defineReactive(obj,key,val){ //这里用到了观察者(订阅/发布)模式,它定义了一种一对多的关系,让多个观察者监听一个主题对象,这个主题对象的状态发生改变时会通知所有观察者对象,观察者对象就可以更新自己的状态。 //实例化一个主题对象,对象中有空的观察者列表 var dep = new Dep(); //将data的每一个属性都设置为Vue对象的访问器属性,属性名和data中相同 //所以每次修改Vue.data的时候,都会调用下边的get和set方法。然后会监听v-model的input事件,当改变了input的值,就相应的改变Vue.data的数据,然后触发这里的set方法 Object.defineProperty(obj,key,{ get: function(){ //Dep.target指针指向watcher,增加订阅者watcher到主体对象Dep if(Dep.target){ dep.addSub(Dep.target); } return val; }, set: function(newVal){ if(newVal === val){ return } val = newVal; //console.log(val); //给订阅者列表中的watchers发出通知 dep.notify(); } }); } //主题对象Dep构造函数 function Dep(){ this.subs = []; } //Dep有两个方法,增加观察者 和 发布消息 Dep.prototype = { addSub: function(sub){ this.subs.push(sub); }, notify: function(){ this.subs.forEach(function(sub){ sub.update(); }); } }
Object.defineProperty 是仅 ES5 支持,且无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。
- Vue双向绑定原理(二)访问器属性defineProperty()
- vue实现双向绑定的原理Object.defineProperty
- Object.defineProperty()/ vue数据绑定原理
- vue双向绑定原理
- Vue源码解读——实现一个双向绑定(Object.defineProperty与observe)
- 理解前端数据双向绑定原理——Object.defineProperty()
- vue双向数据绑定原理
- Vue 双向数据绑定原理
- Vue双向绑定原理(一)文档片段DocumentFragment
- Vue双向数据绑定原理分析
- vue双向数据绑定的原理解密
- 剖析Vue原理&实现双向绑定MVVM
- 剖析Vue原理&实现双向绑定MVVM
- Vue.js双向绑定的实现原理
- 剖析Vue原理&实现双向绑定MVVM
- 转-Vue双向绑定的原理
- 剖析Vue原理&实现双向绑定MVVM
- vue双向数据绑定的原理
- ACM题集以及各种总结大全!
- java数组四种拷贝方式
- libjpeg库的使用(VC6.0环境)
- 使用maven生成mybatis代码
- 前端福利:使用Wallpaper Engine让自己的桌面炫酷起来
- Vue双向绑定原理(二)访问器属性defineProperty()
- 华为机试(二)
- 给定 x, k ,求满足 x + y = x | y 的第 k 小的正整数 y 。 | 是二进制的或(or)运算,例如 3 | 5 = 7。比如当 x=5,k=1时返回 2,因为5+1=6 不等于 5
- automake中Configure.in文件的学习
- 双系统Ubuntu无法进入Windows磁盘的解决方法
- Ubuntu14.04下MRtrix3安装
- linux之vim文本编辑器
- 带着问题学算法之回溯法与八皇后问题
- 单例模式大全