前言:
上一節咱們主要學的是【選項合併】,瞭解了初始化階段各個選項的合併策略,
本節課咱們來學一下【數據代理】這個知識點。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
最後祝您學習進步,早日成爲技術大拿!!!代理