21天完美搞定Vue框架技術(第3天)

前言:
上一節咱們主要學的是【選項合併】,瞭解了初始化階段各個選項的合併策略,
本節課咱們來學一下【數據代理】這個知識點。javascript

一、數據代理的定義
數據代理,也叫做數據劫持。有兩個核心做用:
(1)在訪問對象的屬性時,能夠進行其餘的操做
(2)在修改對象的屬性時,能夠修改返回的結果
說白了,就是會自動觸發一些函數(方法),在該函數(方法)中處理咱們業務邏輯上的需求。前端

二、數據代理的種類
這裏給你們介紹兩種數據代理的方法:
(1) Object.defineProperty()
在一個對象上定義一個新屬性,或修改現有屬性,並返回這個對象。
這個方法有三個參數,分別是:
第一個是原對象,即要操做的對象
第二個是該對象的某個屬性,即要操做的屬性
第三個也是對象,那些會自動觸發的方法就在這裏面
看一個例子:java

var obj = {
    name: '有魚',
    age:2
};
Object.defineProperty(obj, 'name', {
    get() {
        console.log('訪問obj時會自動調用');
        console.log(obj.age);
    },
    set(v) {
        console.log('修改obj屬性時會自動調用');
        obj.age = 5;
    }
})
obj.name;// 訪問obj對象的name屬性,自動調用get(),輸出:訪問obj時會自動調用、2
obj.name = '年年';// 修改obj對象的name屬性,自動調用set(),輸出:修改obj屬性時會自動調用,並且進行了其餘操做,把age變爲5
obj.name;// 再次訪問obj對象的name屬性,自動調用get(),輸出:訪問obj時會自動調用、5

可是這個數據代理的方法是有侷限的,處理一層對象時沒有問題,處理多層級嵌套對象及數組有一些問題,
咱們那處理數組來看一下,第一個參數就是數組自己,第二個參數爲數組的下標,第三個參數仍是同樣的,就是包含set()、get()方法的對象。
仍是看代碼:web

var arr = ['年年', '有魚', '卡卡'];
for(i in arr){
    Object.defineProperty(arr,i,{
        get(){
            console.log('訪問arr時會自動調用'); 
        },
        set(){
            console.log('修改arr時會自動調用');
        }
    });
}
arr[1] = '樓樓';// 修改時,能夠調用set(),輸出:修改arr時會自動調用
console.log(arr);// 訪問時,能夠調用get(),輸出:訪問arr時會自動調用

這種狀況是對原有數組修改,結果是沒有問題的,但若是像 arr[3] = '樓樓' 這樣新增數組時,就不能夠了。
因此說爲了解決這種狀況,就須要使用下面的數據代理方法。
(2) Proxy()
這個數據代理方法其實也比較好理解,就是參照原對象建立一個新的代理對象,咱們的操做都是在這個新對象上完成的。
它有兩個參數,第一個是原來對象,第二個是含有get()、set()的對象
它的返回值就是新建立的代理對象。
並且不單單能夠處理對象,還能夠處理數組及多層級對象嵌套。
看一個例子:數組

var arr = ['年年', '有魚', '卡卡'];
let obj = new Proxy(arr, {
    get: function (target, key, receiver) {
        console.log("獲取時會自動調用" + key);
        return Reflect.get(target, key, receiver);
    },
    set: function (target, key, receiver) {
        console.log('修改時會自動調用');
        return Reflect.set(target, key, receiver);
    }
})

obj[2] = '樓樓';// 修改原有數據,調用set(),結果:修改時會自動調用
console.log(obj[2]);// 訪問數據,調用get(),結果:獲取時會自動調用2
obj[5] = '西瓜' // 添加新數據,調用set(),結果:修改時會自動調用

三、數據代理的應用場景
場景1:Vue當中的數據響應系統使用的是 Object.defineProperty()
這個應用場景後期會單獨分析,今天暫很少說。
場景2:Vue渲染模板時使用的是基於Proxy()新封裝的方法 initProxy()
initProxy()本質上就是對Vue實例化對象作了一層代理,用於一些數據篩選及非法攔截。
例如過濾$,_開頭的Vue內部變量、js的關鍵字、模板使用未定義的變量等。函數

四、兩種數據代理的利弊
Object.defineProperty和Proxy均可以實現數據代理,
前者兼容性較好,可是卻沒法對數組或者嵌套的對象進行代理監測,
後者基本能夠解決全部的問題,可是對兼容性要求很高。學習

後記:
贈人玫瑰,手有餘香!若是以爲文章對您有幫助,
請給一個大大的贊,還能夠分享讓更的人知道哦!
您也是web前端學習者,能夠加VX:qingyulan52
最後祝您學習進步,早日成爲技術大拿!!!代理

相關文章
相關標籤/搜索