Proxy对象是ES6引入的原生化的代理对象,和基于defineProperty实现数据劫持在思路上其实并没有什么本质区别,都是使用经典的“代理模式”来实现的,只是原生支持的Proxy编写起来更简洁,整个天然支持对数组变化的感知能力。Proxy和Reclect对象基本是成对出现使用的,属于元编程范畴,可以从语言层面改变原有特性,Proxy可以拦截对象的数十种方法,比手动实现的代理模式要清晰很多,也要方便很多。
基本实现如下:
//使用Proxy代理数据模型对象 let watchVmData = (obj, setBind, getLogger) => { let handler = { get(target, property, receiver){ getLogger(target, property); return Reflect.get(target, property, receiver); }, set(target, property, value, receiver){ setBind(value); return Reflect.set(target, property, value); } }; return new Proxy(obj, handler); }; //使用Proxy代理 let data = { myname : 1 }; let value; let vmproxy = watchVmData(obj, (v) => { value = v; },(target, property)=>{ console.log(`Get ${property} = ${target[property]}`); }); 四. What's next数据绑定只是MVVM模型中的冰山一角,如果你自己动手实现了上面提及的Demo,一定会发现很多明显的问题,例如订阅者刷新函数是直接修改DOM的,稍有开发经验的前端工程师都会想到需要将变化收集起来,尽可能将高性能消耗的DOM操作合并在一起处理来提升效率,这就引出了一系列我们常常听到的Virtual-DOM(虚拟DOM树)和Life-Cycle-Hook(生命周期钩子)等等知识点,如果你对三大框架的底层原理感兴趣,可以继续探索,那是一件非常有意思的事情。
五. 总结通过原理的学习就会发现学习【设计模式】的重要性,很多时候别人用设计模式的术语交流并不是在装X,而是它真的代表了一些久经验证的思想,仅仅是数据绑定这样一个小小的知识点,就包含了类模式,代理模式,原型模式,策略模式,发布订阅模式的运用,代码的实现中也涉及到了单一职责,开放封闭等等开发原则的考量,框架编写是一件非常考验基本功的事情,在基础面前,技巧只能是浮云。