面试问:如何在IE8如下实现数据的双向绑定

Object.defineProperty

咱们都知道Vue是使用Object.defineProperty来实现的数据双向绑定。咱们先来实现一下数据的双向绑定。html

var obj = {};
var a;
Object.defineProperty(obj,'a',{
    get: function(){
        console.log('get val');
        return a;
    },
    set: function(newVal){
        console.log('set val : ' + newVal);
        a = newVal;
    }
})
复制代码

这样就能够实现一个数据的双向绑定。若是加上input只要稍微改造一下就能够面试

<input type="text" id="input">
复制代码

js部分浏览器

var input = document.querySelector("#input");
var obj = {};
var a;
Object.defineProperty(obj, 'a', {
    get: function () {
        return a;
    },
    set: function (newVal) {
        input.value = newVal;
        a = newVal;
    }
})
input.addEventListener('input', function (e) {
    obj.a = e.target.value;
    console.log(obj.a);
})
复制代码

这样就实现了一个双向数据绑定,可是 Object.defineProperty并非完美的,它有优势也有缺点。

  • 优势:对一个对象能够作到完整的监听。
  • 缺点:Object.defineProperty是ES5的API,向下兼容性很很差。

面试有时候也常常会问到:怎么样实现IE8及一下的双向数据绑定。框架

对于上面这个问题,咱们可使用API的私有属性。函数

defineGetter__和__defineSetter

咱们常常见到的__proto__凡是以__开头结尾的是浏览器的私有属性,__defineGetter__和__defineSetter__一样也是私有属性,这两个属性和Object.defineProperty同样都是对对象添加属性,Object.defineProperty至关于这两个方法的合并。ui

怎么使用它呢?spa

这两个方法接收两个参数:双向绑定

  • 第一个参数是定义属性的名字。
  • 第二个参数是一个函数。

例如:给obj对象添加一个name属性code

obj.__defineSetter__('name',function(val){
    console.log('set name :' + val);
})
obj.__defineGetter__('name',function(){
    console.log('get name');
})
复制代码

如何使用这个API实现数据的双向绑定呢?咱们来实现一下。

var input = document.querySelector("#input");
var obj = {};
input.addEventListener('input', function (e) {
    obj.name = e.target.value;
    console.log(obj.name);
})
var name;
obj.__defineSetter__('name',function(val){
    input.value = val;
    name = val;
})
obj.__defineGetter__('name',function(){
    return name;
})
复制代码

哎呦,不错哦。

其余方式

在Vue未出现以前,也是有MVVM框架产生的,好比说San.js,它也是传统的MVVM数据双向绑定而且兼容IE6。还有VBScript,在VBScript中能够写类,类中能够定义getter和setter,一样能够实现数据的双向绑定。cdn

因为我本身能力有限,在这里就实现这么多了,若是各位有兴趣的话,能够本身实现一下。

相关文章
相关标签/搜索