常见双向绑定的实现方法
(1)KnockoutJS 基于观察者模式的双向绑定;
(2)Ember 基于数据模型的;
(3)Angular 基于脏检查的双向绑定,使用主动遍历
(4)基于数据劫持的双向绑定
A.Vue现在使用的Object.defineProperty
B.ES6新增的Proxy。
基于数据劫持双向绑定的优点
无需显示调用
data.name = ‘Bingle’; 就能直接触发变更
不用像react使用setState显示调用;
可以精确得到变化数据
劫持属性的setter变化时可以得到newVal;否则只知道数据变了,具体需要大量的diff才能找出变化值;
基于Object.defineProperty双向绑定的两个缺点
无法监听数组的变化
根本原因:数组没有setter和getter,因为数组的长度不确定,可能会很大,出于性能考虑就没有setter和getter。
注:vue文档说可以检测数组变化,其实是使用了奇技淫巧,
实现代码思路如下:
1 | const aryMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']; |
只能劫持对象的属性
我们需要对每个对象的每个属性进行遍历,如果属性值也是对象,就要深度遍历了。
所以要放大招了~
Proxy实现双向绑定的特点
严格讲proxy叫做代理,提供了一种机制能对外界访问进行过滤和改写,简单理解Proxy是Object.defineProperty的全方位加强版
优点
(1)直接监听整个对象,而不是属性
(2)可以监听数组的变化
(3)Proxy有多达13种拦截方法,很多都是Object.defineProperty不具备的。
(4)返回一个新的对象,不是像Object.defineProperty那样直接修改对象属性;符合immutable思想;
(5)新标准的性能红利,会受到浏览器厂商重点持续的心性能优化
缺点
兼容性问题,且无法用polyfill磨平,所以尤大才说要等到大版本3.0再用Proxy重写了。
参考文章:
掘金: 面试官: 实现双向绑定Proxy比defineproperty优劣如何?
以上
欢迎随时交流~
如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理