今天我們將嘗試下花 1 分鐘的時間簡單地了解下什么是 JS 代理對象(proxies)?我們可以這樣理解,JS 代理就相當于在對象的外層加了一層攔截,在攔截方法里我們可以自定義一些個性化的邏輯,定義完后我們可以通過代理定義的方法間接操作對象。再說得通俗點,在我們的生活中,我們買房租房一般不找房東先找中介的道理一樣,因為中介充當了房源的代理一樣。
接下來我們通過代碼理解下什么是代理,用JS創(chuàng)建代理比較簡單,如下段代碼所示:
let initialObject = { /* 定義對象 */ };
let handler = { /* 自定義相關(guān)的攔截器處理邏輯 */ };
let proxyedObject = new Proxy(initialObject, handler);
簡單解釋下,我們可以通過代理去調(diào)用 handler 里定義的邏輯去操作對象,對象代理有兩個參數(shù),initialObject 是目標對象,handler 攔截器對象(或者稱作處理器對象)。
接下來,我們來看一個例子,我們通過代理實現(xiàn)讀取一個對象的屬性,如果對象的屬性不存在,則返回代理中定義的默認值,這里我們在代理里重寫了原有對象的 get 方法。
let dog = {
name: "Spike"
};
const handler = {
get: (obj, property) => property in obj ? obj[property] : 'You don't have defined a property named ' + property;
}
const proxyDog = new Proxy(dog, handler);
console.log(proxyDog.name);
// 將會輸出 Spike
console.log(proxyDog.age);
// 輸出 You don't have defined a property named age
上述例子,我們通過 get: (obj, property) => ... 方法重寫了對象的 get 方法。
最后我再看一個如何通過代理去更對對象的值,如果更新的值不是我們期望的值,系統(tǒng)則拋出異常錯誤,不能正常更新,否則重新賦值并更新對象的屬性。
let dog = {
name: "Spike",
age: 1;
};
let handler = {
set: (obj, property, value) => {
if (property === 'age') {
if (!Number.isInteger(value)) throw new TypeError('Use numbers only for age');
if ((value < 0) || (value > 30)) throw new RangeError('A dog can't live that long');
}
obj[prop] = value;
return true;
}
};
const proxyDog = new Proxy(dog, handler);
proxyDog.age = -1;
// will throw A dog can't live that long
proxyDog.age = 'very old';
// will throw Use numbers only for age
通過 JS 代理我們不僅可以重寫 getters 和 setters 方法,我們還可以進行這些操作:deleteProperty、construct、getOwnPropertyDescriptor 等...
今天的文章就到這里,不知道你是否理解代理對象啦,在接下來的文章里,我們再聊聊代理在實際項目中的運用,感謝你的閱讀。
參考來源:http://www.js-craft.io/blog/what-are-JAVAscript-proxies/
Daniel