面試問:如何在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

因爲我本身能力有限,在這裏就實現這麼多了,若是各位有興趣的話,能夠本身實現一下。

相關文章
相關標籤/搜索