var data = { price: 5, quantity: 2 };var data_without_proxy = data; // 保存源对象
data = new Proxy(data_without_proxy, {
// 重写数据以在中间创建一个代理
get(obj, key) {
console.log(obj+'取值')
},
set(obj, key, newVal) {
console.log(obj+"设置值")
}
});
data.price = 8 //设置
data.price //取值
【第1420期】JavaScript 响应式与 Proxy
前言
前端的温度下降了吗?今日早读文章由@李金超推荐,汽车之家@花生翻译分享。
@花生,就职于汽车之家用户产品中心团队,云云搬砖码农的中的一员。
正文从这开始~~
Vue与Proxy
在之前的文章中,我们模拟了Vue的响应式引擎。使用Object.defineProperty()通过getters/setters实现属性的响应性。
如果你一直有关注Vue的发展,就会发现2.x-next版本开始其响应式引擎将使用Proxy重写,这就与我们之前讲的不同了。
1-1响应式引擎利用代理进行重写——标黄线的(译者注)。
I wanted to ask Evan what exactly this might look like and the advantages we get from it(当成一句玩笑吧).
这样做的好处
Proxy允许我们创建一个对象的虚拟代理(替代对象),并为我们提供了在访问或修改原始对象时,可以进行拦截的处理方法(handler),如set()、get()和deleteProperty()等等。这样我们就可以避免很常见的这两种限制:
-
添加新的响应性属性要使用Vue.$set(),删除现有的响应性属性要使用Vue.$delete()。
-
数组的更新检测。
之前的代码
我们之前使用Object.defineProperty()来实现监听属性的访问和修改这两种操作,代码如下:
let data = { price: 5, quantity: 2 }
let target = null
class Dep {
constructor () {
this.subscribers = []
}
depend () {
if (target && !this.subscribers.includes(target)) {
this.subscribers.push(target)
}
}
notify () {
this.subscribers.forEach(sub => sub())
}
}
Object.keys(data).forEach(key => {
let internalValue = data[key]
const dep = new Dep()
Object.defineProperty(data, key, {
get() {
dep.depend()
return internalValue
},
set(newVal) {
internalValue = newVal
dep.notify()
}
})
})
function watcher(myFun) {
target = myFun
target()
target = null
}
watcher(() => {
data.total = data.price * data.quantity
})
console.log("total = " + data.total)
data.price = 20
console.log("total = " + data.total)
data.quantity = 10
console.log("total = " + data.