关于vue.js:vue源码分析基础的数据代理检测
简略回顾一下这个系列的前两节,前两节花了大量的篇幅介绍了Vue的选项合并,选项合并是Vue实例初始化的开始,Vue为开发者提供了丰盛的选项配置,而每个选项都严格规定了合并的策略。然而这只是初始化中的第一步,这一节咱们将对另一个重点的概念深刻的剖析,他就是数据代理,咱们晓得Vue大量利用了代理的思维,而除了响应式零碎外,还有哪些场景也须要进行数据代理呢?这是咱们这节剖析的重点。2.1 数据代理的含意数据代理的另一个说法是数据劫持,当咱们在拜访或者批改对象的某个属性时,数据劫持能够拦挡这个行为并进行额定的操作或者批改返回的后果。而咱们晓得Vue响应式零碎的外围就是数据代理,代理使得数据在拜访时进行依赖收集,在批改更新时对依赖进行更新,这是响应式零碎的外围思路。而这所有离不开Vue对数据做了拦挡代理。然而响应式并不是本节探讨的重点,这一节咱们将看看数据代理在其余场景下的利用。在剖析之前,咱们须要把握两种实现数据代理的办法: Object.defineProperty 和 Proxy。 2.1.1 Object.defineProperty官网定义:Object.defineProperty()办法会间接在一个对象上定义一个新属性,或者批改一个对象的现有属性, 并返回这个对象。根本用法: Object.defineProperty(obj, prop, descriptor)Object.defineProperty()能够用来准确增加或批改对象的属性,只须要在descriptor对象中将属性个性形容分明,descriptor的属性描述符有两种模式,一种是数据描述符,另一种是存取描述符,咱们别离看看各自的特点。 数据描述符,它领有四个属性配置configurable:数据是否可删除,可配置enumerable:属性是否可枚举value:属性值,默认为undefinedwritable:属性是否可读写存取描述符,它同样领有四个属性选项configurable:数据是否可删除,可配置enumerable:属性是否可枚举get:一个给属性提供 getter 的办法,如果没有 getter 则为 undefined。set:一个给属性提供 setter 的办法,如果没有 setter 则为 undefined。须要留神的是: 数据描述符的value,writable 和 存取描述符中的get, set属性不能同时存在,否则会抛出异样。 有了Object.defineProperty办法,咱们能够不便的利用存取描述符中的getter/setter来进行数据的监听,这也是响应式构建的雏形。getter办法能够让咱们在拜访数据时做额定的操作解决,setter办法使得咱们能够在数据更新时批改返回的后果。看看上面的例子,因为设置了数据代理,当咱们拜访对象o的a属性时,会触发getter执行钩子函数,当批改a属性的值时,会触发setter钩子函数去批改返回的后果。 var o = {}var value;Object.defineProperty(o, 'a', { get() { console.log('获取值') return value }, set(v) { console.log('设置值') value = qqq }})o.a = 'sss' // 设置值console.log(o.a)// 获取值// 'qqq'后面说到Object.defineProperty的get和set办法是对对象进行监测并响应变动,那么数组类型是否也能够监测呢,参照监听属性的思路,咱们用数组的下标作为属性,数组的元素作为拦挡对象,看看Object.defineProperty是否能够对数组的数据进行监控拦挡。 var arr = [1,2,3];arr.forEach((item, index) => { Object.defineProperty(arr, index, { get() { console.log('数组被getter拦挡') return item }, set(value) { console.log('数组被setter拦挡') return item = value } })})arr[1] = 4;console.log(arr)// 后果数组被setter拦挡数组被getter拦挡4显然,已知长度的数组是能够通过索引属性来设置属性的拜访器属性的。然而数组的增加确无奈进行拦挡,这个也很好了解,不论是通过arr.push()还是arr[10] = 10增加的数据,数组所增加的索引值并没有事后退出数据拦挡中,所以天然无奈进行拦挡解决。这个也是应用Object.defineProperty进行数据代理的弊病。为了解决这个问题,Vue在响应式零碎中对数组的办法进行了重写,间接的解决了这个问题,具体细节能够参考后续的响应式系统分析。 ...