JavaScript的Proxy對象詳解
一、Proxy 是什麼?
Proxy 對象用於攔截並修改目標對象的指定操作。
// 語法 const p = new Proxy(target, handler)
- target :目標對象(可以是任何類型的對象,包括原生數組,函數,甚至另一個代理)。
- handler :以函數作為屬性的對象,實現攔截和自定義操作。
二、怎麼用?
1、使用 Proxy 的簡單實例
訪問不存在的屬性,設置默認值返回而不返回 undefined ,get handler 有其具體語法規則,看這裡!
// 1、找到合適的 handler 並編寫代碼 const handler = { get: function(obj, prop) { return prop in obj ? obj[prop] : 37; } }; // 2、新建 Proxy 對象 const p = new Proxy({}, handler); // 3、執行操作 p.a = 1; p.b = undefined; // 4、查看結果 console.log(p.a, p.b); // 1, undefined console.log('c' in p, p.c); // false, 37
2、目標對象被正確修改
let target = {}; let p = new Proxy(target, {}); p.a = 37; // 操作轉發到目標 console.log(target.a); // 37. 操作已經被正確地轉發
3、使用 set handler 做數據驗證
set handler 有其具體的語法規則,看這裡!
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; // 表示成功 return true; } }; 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
4、擴展構造函數
construct handler 的具體語法規則,看這裡!
function extend(sup, base) { var descriptor = Object.getOwnPropertyDescriptor( base.prototype, "constructor" ); base.prototype = Object.create(sup.prototype); var handler = { construct: function(target, args) { var obj = Object.create(base.prototype); this.apply(target, obj, args); return obj; }, apply: function(target, that, args) { sup.apply(that, args); base.apply(that, args); } }; var proxy = new Proxy(base, handler); descriptor.value = proxy; Object.defineProperty(base.prototype, "constructor", descriptor); return proxy; } var Person = function (name) { this.name = name }; var Boy = extend(Person, function (name, age) { this.age = age; }); Boy.prototype.sex = "M"; var Peter = new Boy("Peter", 13); console.log(Peter.sex); // "M" console.log(Peter.name); // "Peter" console.log(Peter.age); // 13
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- JavaScript Object.defineProperty與proxy代理模式的使用詳細分析
- 前端JavaScript中的反射和代理
- Vue自定義指令中無法獲取this的問題及解決
- js Proxy的原理詳解
- 一篇文章搞懂JavaScript中的代理和代理的使用