对于前端,有时候须要实现视图层和数据层的双向绑定(two-way-binding), 例如当前流行的各类框架和类库:Vue.js、Angular.js、React.js。 然而,他们最原始的实现方式其实都相对比较简单,只不过是后来随着各类Bug的出现,才一如滚雪球般地被不断优化和壮大。javascript
因此,不要畏惧,多多学习并摄取它们的精华。html
这里, 我也但愿经过简单的思路让你对数据的双向绑定有个大概了解,而后去看各类MVVM框架中对于数据双向绑定的实现才不会一头雾水。前端
Element继承了Node,而Element是众多Node类型中的其中一个, nodeType === 1, 因此,属于Node的属性能够用于Element,但Element的属性没法用于Node,听起来好拗口,看一下代码吧.java
<div class="demo"> <p>大</p> <p>轰</p> </div> var el = document.querySelector('.demo'); // true console.log(el.children[0] instanceof Node); // true console.log(el.children[0] instanceof Element); // true console.log(el.childNodes[0] instanceof Node); // false console.log(el.childNodes[0] instanceof Element); // undefined console.log(typeof el.childNodes[0].children); // object console.log(typeof el.childNodes[0].childNodes);
双向绑定对于理解Flux等架构所提倡的单向数据流特性有很好的帮助, 简单点说,就是将数据的变化绑定到UI, 同时UI的变化又和数据同步。这样一来,假如你是全站Ajax,你不用去管数据对UI的影响,同时也不用去管UI变化形成的数据变化,统一了数据操做的入口,很是方便维护。(不知道这样理解对不对, 望指正)node
总而言之,双向数据绑定的底层实现大概有两种:git
一、手动绑定,同时使用dirty check去循环监听。(Angular.js为表明)github
二、前端数据劫持。(使用defineProperty, Vue.js貌似就是使用这种)架构
这种方法的实现相似**订阅者模式**,实现思路是经过DOM的*keydown* *keyup* *keypress* *change*等事件触发*dirty check*(固然你也能够用setTimeout), 而后循环监听并将value写入某实例变量里面,同时更新DOM。
如果有时间,推荐去看一下Angular.js文档中关于digest / $watch的介绍。框架
若是使用jQuery实现起来更加简单明了。
传送门在此frontend
https://jsfiddle.net/fondadam/sdxhhoLx/2/embedded/js,html,result
第三种方法则是Vue.js
等框架使用的数据劫持方式。基本思路是使用Object.defineProperty
对数据对象作属性get和set的监听,当有数据读取和赋值操做时则调用节点的指令,这样使用最通用的=等号赋值就能够触发了。
https://jsfiddle.net/fondadam/a4qhp06s/embedded/js,html,result