ES6規範定義了一個全新的全局構造函數:代理(Proxy)。vue
它能夠接受兩個參數:es6
target:用Proxy
包裝的目標對象(能夠是任何類型的對象,包括原生數組,函數,甚至另外一個代理)。chrome
handle: 一個對象,其屬性是當執行一個操做時定義代理的行爲的函數。數組
基礎示例函數
let handler = { get: function(target, name){ return name in target ? target[name] : 37; } }; let p = new Proxy({}, handler); p.a = 1; p.b = undefined; console.log(p.a, p.b); // 1, undefined console.log('c' in p, p.c); // false, 37
在上面的例子中,咱們對一個對象進行了代理,當對象中不存在屬性名時,缺省返回數爲37
。學習
無操做轉發代理ui
let target = {}; let p = new Proxy(target, {}); p.a = 37; // 操做轉發到目標 console.log(target.a); // 37. 操做已經被正確地轉發
對象傳值驗證spa
let validator = { set: function(obj, prop, value) { if (prop === 'age') { if (!Number.isInteger(value)) { throw new TypeError('The age is not an integer'); } if (value > 200) { throw new RangeError('The age seems invalid'); } } // The default behavior to store the value obj[prop] = value; } }; let person = new Proxy({}, validator); person.age = 100; console.log(person.age); // 100 person.age = 'young'; // 拋出異常: Uncaught TypeError: The age is not an integer person.age = 300; // 拋出異常: Uncaught RangeError: The age seems invalid
最近在學習vue.js的源碼,發現不少地方都用到了proxy代理來進行驗證,好比說keycodes的設置3d
先看官網的說明代理
看源碼中對keycodes的驗證
//vue/src/core/instance/proxy.js /** *.... */ const hasProxy = typeof Proxy !== 'undefined' && Proxy.toString().match(/native code/) if (hasProxy) { const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact') config.keyCodes = new Proxy(config.keyCodes, { set (target, key, value) { if (isBuiltInModifier(key)) { warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`) return false } else { target[key] = value return true } } }) } /** *.... */
對config的keyCodes對象進行了代理,當設置其屬性時就會進行驗證,若是是這是stop,prevent,self,ctrl,shift,alt,meta,exact這些屬性,就會報錯
當我這樣設置的時候
Vue.config.keyCodes.ctrl = 13;
就會獲得這樣的結果
proxy對象其實就至關於一個對象攔截器,能夠觀察或記錄對象訪問。其應用場景固然確定不單單用於驗證,這裏暫時就不深刻學習了。不過話說回來,proxy對象做爲es6的標準,其兼容性不是很好,目前只有Firefox,chrome和微軟的Edge支持代理,並且尚未支持這一特性polyfill。因此,這個屬性仍是須要謹慎使用誒。。