Object.defineProperty
循环执行Object.defineProperty方法遍历对象的每一个属性,给每一个属性增加get和set方法,使得我们在读取和设置属性值的时候都会被Vue给监听到,从而去做一些其他的操作。
代码示例:
let obj = {
a:1,
b:2,
c:{
d:3,
e:4,
f:{
g:6
}
}
}
function observe(obj){
for(const k in obj){
let v = obj[k]
if(isObject(v)){
observe(v)
}
Object.defineProperty(obj,k,{
get(){
console.log('读取了属性',k)
return v
},
set(val){
if(val !== v){
console.log(`设置了属性${k}`,val)
v = val
}
}
})
}
}
function isObject(v){
return typeof v == 'object' && v !== null
}
observe(obj)
let v = obj.c.d
obj.a =3
输出结果:
Proxy
Proxy 对象来拦截对对象属性的访问和修改操作。通过 Proxy 的 get 和 set 方法, 可以监控属性的读取和写入,并进行相应的更新
代码示例:
let obj = {
a: 1,
b: 2,
c: {
d: 3,
e: 4,
f: {
g: 6
}
}
}
function observe(obj) {
const proxy = new Proxy(obj, {
get(target, k) {
let v = target[k]
if (isObject(v)) {
v = observe(v)
}
console.log('读取了', k)
return v
},
set(target, k, val) {
if (target[k] !== val) {
console.log('设置了值', val)
target[k] = val
}
}
})
return proxy
}
function isObject(v) {
return typeof v == 'object' && v !== null
}
let proxy = observe(obj)
proxy.a = 3
proxy.c.f.g
proxy.c.f.g = 9
proxy.VV //没有的属性依旧可以监听的到
输出结果:
总结
1.Proxy的效率比Object.defineProperty高,原因是Object.defineProperty需要递归遍历对象的每一个属性设置set和get,而Proxy只有用到了这个属性才会深度遍历寻找。
2.Proxy对于新增的属性也可以读取,而Object.defineProperty只在对象创建时生成属性的set和get,对于新增的属性无法做到监听。