defineProperty和proxy的区别
响应式的目的
当对象属性被读取后,被修改后,我要介入进行一些操作。
属性值的读和修改变成函数
defineProperty
他是针对属性的监听,所以对obj下的每个属性(深度遍历)进行监听。
天生缺陷:深度遍历效率缺失;由于遍历,新增属性他是没有被监听的;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const obj = { a:1, b:2, c:{ d:3, e:4 }, } function _isObject(v){ return typeof v==='object' && v != null } function observe(obj){ for(const k in obj){ let v = obj[k] if (_isObject(v)){ observe(v) } Object.defineproperty(obj,'a',{ get(){ console.log('a','读取') return v }, set(newval){ if(v != newval){ v = newval console.log('a','更改') } } }) } }
|
proxy监听整个对象
Proxy返回一个新的代理对象,不动原数据
监听的是整个对象,所以不需要遍历,新增时可以收到通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| const obj = { a:1, b:2, c:{ d:3, e:4 }, } function _isObject(v){ return typeof v==='object' && v != null }
function observe(obj){ const proxy = new Proxy(obj,{ get(target,k){ let v = target[k] if(_isObject(v)){ observe(v) } console.log(k,'读取') return v }, set(target,k,val){ if(target[k] != val){ target[k] = val } } }) return proxy }
const proxy = new Proxy(obj,{ get(target,k){ let v = target[k] console.log(k,'读取') return v }, set(target,k,val){ if(target[k] != val){ target[k] = val } } })
|