- 全部用ts重写(响应式、vdom、模版编译等)
- 性能提升, 代码量减少
- 会调整部分API
| | Object.defineProperty | Proxy |
| —- | —- | —- |
| 优点 | | 规避Object.ownPerporty的问题:
- 深度监听惰性递归(性能提升)
- 可监听新增/删除 属性
- 可监听数组变化
| | 缺点 |
- 深度监听需要一次性递归到底(计算量大)
- 无法监听新增属性/删除属性(vue.$set、vue.$delete)
- 无法原生监听数组, 需要特殊处理
| 存在浏览器兼容性问题, 且不能ployfill |
实现响应式
- 重复数据不监听
- 新增属性监听
- 深度监听
- 性能提升
优化1,监听数组, 调用原型方法,分布执行get push、get length、set 3 d、set length 4。
过滤掉get push, 自带原型属性, 无需处理。
过滤掉set length 4, 在set 3 d中已处理, 无需重复处理。
get(target, key, receiver) {const ownKeys = Reflect.ownKeys(target)// 只处理本身(非原型的)属性if (!ownKeys.includes(key)) {console.log('get', key)}const result = Reflect.get(target, key, receiver)return result},set(target, key, val, receiver) {// 重复数据不处理if (val === target[key]) {return true}const result = Reflect.set(target, key, val, receiver)console.log('set', key, val)return result},
优化2, 监听新增属性(及区分出新增属性)
if (!Reflect.ownKeys(target).includes(key)) {console.log('new', key)}
优化3, 深度监听+性能提升
if (typeof target != 'object' || target == null) {// 不是对象或数组, 则返回return target}set () {// 深度监听return observe(result)}
基本用法
const data = {name: 'Jack',age: 24}const proxyData = new Proxy(data, {get(target, key, receiver) {const result = Reflect.get(target, key, receiver)console.log('get', key)return result},set(target, key, val, receiver) {const result = Reflect.set(target, key, val, receiver)console.log('set', key, val)return result},deleteProperty(target, key) {const result = Reflect.deleteProperty(target, key)console.log('delete', key)return result}}console.log(data.name)proxyData.nameproxyData.name = 'Lucy'console.log(proxyData)delete proxyData.ageconsole.log(proxyData)
Refect
- 和Proxy能力—对应
- 规范化、标准化、函数式
- 替代掉Object上的工具函数
const data = {name: 'Jack',age: 24,city: 'chengdu'}// [ 'name', 'age' ]console.log(Object.getOwnPropertyNames(data))console.log(Reflect.ownKeys(data))// trueconsole.log('name' in data)console.log(Reflect.has(data, 'name'))// deletedelete data.ageReflect.deleteProperty(data, 'city')console.log(data)
