随着MVVM框架的广泛使用响应式数据已经变得耳熟能详,现在谈响应式数据好像有点炒冷饭的意思,对!没错!不过这次炒的是蛋炒饭,而且还是加火腿肠的那种。之前看过几个框架的响应式数据实现,貌似都对数组(Array)做了特殊处理,咋的啦,有这么特别吗?看来是时候反思和总结一波了。
如何实现响应式数据
首先来简单实现一个响应式对象。easy! ES5在Object对象中新增了defineProperties和defineProperty两个方法用来对对象的属性进行描述,其中的setter和getter这一对CP就是实现响应式对象的关键,先来看一段简单的代码
const person = {
name:"wyy",
age:"18"
}
Object.defineProperty(person,name,{
get(){
console.log(`没错,我就是人见人爱,车见爆胎的wyy`);
return "wyy"
},
set(newVal){
console.log('俺老王,行不更名,坐不改姓')
return
}
})
没错就是这么简单,这是目前普遍的实现方式。当然了,这段代码只是响应式的一部分,在get中进行依赖搜集,在set中通知收集来的依赖进行相应的处理,然后再搭配上高大上的观察者模式,这样响应式系统才基本成型,大部分响应式数据的实现都是这个路数,比如看过Vue2.x的响应式数据源码会发现几个关键字Observe,Watcher,Dep,notify,从字面意思来看大概也就是这么个路数,这里就不展开说了,毕竟掘金上个个都是人才,上面有不下50篇文章分析vue的响应式数据,篇篇精彩。
好了分析结束。wait…wait…wait…标题好像是谈数组的响应式,跑题了
实现一个响应式数组
下面来说所数组,没记错的话数组也是继承自Object,它算一种特殊的对象,那么数组能用Object.defineProperty来实现响应式吗?不说了,打开VSCode就是干
const arr = ["2019","云","栖","音","乐","节"];
arr.forEach((val,index)=>{
Object.defineProperty(arr,index,