什麼是代理
代理人在行動
誰使用代理
使用案例和實例
資源簡介
開始吧:)
什麼是代理正如MDN網站上所說。
Proxy對象可以讓你為另一個對象創建一個代理,它可以攔截和重新定義該對象的基本操作。
在解釋什麼是Proxy的時候,說它可以創建一個Proxy,這有點搞笑。當然,他們並沒有說錯,但是我們可以簡化這個說法,讓它更加友好。
Proxy對象使你能夠包裝目標對象 通過這樣可以攔截和重新定義該對象的基本操作。
基本上,它的意思是說,我們要把一個對象,用Proxy包裹起來,這將允許我們創建一個 "隱藏 "的門,並控制所有對所需對象的訪問。
一個小插曲,Proxy也是一種軟體設計模式,你一定要讀一讀(維基百科連結)。
一個Proxy的創建有兩個參數。
代碼
const target = {
message1: "hello",
message2: "everyone"
};
const handler = {};
const proxy = new Proxy(target, handler);
大多數瀏覽器都支持代理功能,但也有一些老的瀏覽器不支持(當然是IE),你可以在這裡查看完整的列表。google有一個代理的polyfill,但它不支持所有的代理功能。
現在知道了什麼是Proxies,想看看能用它做什麼。
代理人在行動讓我們想像一下,我們是一家銀行或一個憂心忡忡的女朋友。我們想知道每次銀行帳戶餘額被訪問和被通知的時間。我們將使用最簡單的處理程序操作/trap: get
const bankAccount = {
balance: 2020,
name: 'Georgy Glezer'
};
const handler = {
get: function(target, prop, receiver) {
if (prop === 'balance') {
console.log(`Current Balance Of: ${target.name} Is: ${target.balance} `);
}
return target[prop];
}
};
const wrappedBankAcount = new Proxy(bankAccount, handler);
wrappedBankAcount.balance; // access to the balance
// OUTPUT:
// Current Balance Of: Georgy Glezer Is: 2020
// 2020
在上面的例子中,我們有一個銀行帳戶對象,裡面有我的名字和2020的餘額。
這次的處理者對象是實現get操作/trap,它接收一個有3個參數的函數和get的返回值。
我們定義了一個條件,如果被訪問的屬性是 "餘額",我們將通知(log)餘額和當前用戶名,並返回 "餘額 "屬性。
從輸出中可以看到,一旦 "balance "屬性被訪問,我們就通過使用Proxy和設置get操作/陷阱,很容易地通知(log)了這次訪問。
繼續我們銀行的想法,要求每次有人從銀行帳戶中取錢,我們都要得到通知。而另一個約束條件是,銀行不允許出現負餘額。為了達到這個目的,我們這次要使用設置處理程序/陷阱。
const bankAccount = {
balance: 2020,
name: 'Georgy Glezer'
};
const handler = {
set: function (obj, prop, value) {
console.log(`Current Balance: ${obj.balance}, New Balance: ${value}`);
if (value < 0) {
console.log(`We don't allow Negative Balance!`);
return false;
}
obj[prop] = value;
return true;
}
};
const wrappedBankAcount = new Proxy(bankAccount, handler);
wrappedBankAcount.balance -= 2000; // access to the balance
console.log(wrappedBankAcount.balance);
wrappedBankAcount.balance -= 50; // access to the balance
console.log(wrappedBankAcount.balance);
// OUTPUT:
// Current Balance: 2020, New Balance: 20
// 20
// Current Balance: 20, New Balance: -30
// We don't allow Negative Balance!
// 20
在上面的例子中,我們通知當前的餘額和取款後的新餘額,如果新的餘額是負數,我們也會通知並中止取款操作。
我們使用的是set operator/trap,它是一個返回布爾值(true/false)的函數,用來判斷更新操作是否成功。它接收以下參數。
你可以看到,它和get真的很相似,但只是多接收了1個新值的參數。
這2個操作符/陷阱是最常見的,如果你有興趣找到所有現有的操作符/陷阱,你可以在這裡查看。
誰使用代理許多流行的庫都使用了這種技術,例如。
還有更多.他們中的大多數人都利用了Proxies給我們帶來的驚人力量,並為我們提供了很棒的庫。
使用案例和實例我們已經看到,我們可以使用代理伺服器來進行。
緩存我們將再次使用get operator/trap,並將 "dollars "屬性添加到我們的對象中。在每次訪問 "dollars "屬性時,我們將計算我們的餘額價值多少美元。因為計算可能是一個沉重的操作,我們希望儘可能多的Cache它。
const bankAccount = {
balance: 10,
name: 'Georgy Glezer',
get dollars() {
console.log('Calculating Dollars');
return this.balance *3.43008459;
}
};
let cache = {
currentBalance: null,
currentValue: null
};
const handler = {
get: function (obj, prop) {
if (prop === 'dollars') {
let value = cache.currentBalance !== obj.balance ? obj[prop] : cache.currentValue;
cache.currentValue = value;
cache.currentBalance = obj.balance;
return value;
}
return obj[prop];
}
};
const wrappedBankAcount = new Proxy(bankAccount, handler);
console.log(wrappedBankAcount.dollars);
console.log(wrappedBankAcount.dollars);
console.log(wrappedBankAcount.dollars);
console.log(wrappedBankAcount.dollars);
// OUTPUT:
// Calculating Dollars
// 34.3008459
// 34.3008459
// 34.3008459
// 34.3008459
正如你在例子中所看到的,我們有一個緩存對象,它保存著當前的銀行餘額和以美元為單位的餘額價值。每次有人訪問 "dollar "屬性時,我們都會先進行計算,然後將其緩存起來。
Dom操作我們想在每次餘額發生變化時更新屏幕上的文字。我們將使用一個set操作符/trap,每次改變數值時,我們將更新屏幕上的DOM元素。
const bankAccount = {
balance: 2020,
name: "Georgy Glezer",
get text() {
return `${this.name} Balance Is: ${this.balance}`;
}
};
const objectWithDom = (object, domId) => {
const handler = {
set: function (obj, prop, value) {
obj[prop] = value;
document.getElementById(domId).innerHTML = obj.text;
return true;
}
};
return new Proxy(object, handler);
};
// create a dom element with id: bank-account
const wrappedBankAccount = objectWithDom(bankAccount, "bank-account");
wrappedBankAccount.balance = 26;
wrappedBankAccount.balance = 100000;
在這裡,我們創建了一個輔助函數,這樣我們就可以存儲DOM元素的ID,並在set operator/trap中添加了簡單的行來更新DOM元素。很簡單,對吧?讓我們看看結果:)
概要綜上所述,我們了解了ECMAScript 6 Proxies,我們如何使用它們,以及用於什麼目的。在我看來,代理是一個神奇的工具,你可以用它來做各種各樣的選擇,你只需要考慮什麼是最適合你的:) 。
資源關於本文譯者:飄飄作者:@Georgy Glezer原文:https://levelup.gitconnected.com/the-amazing-power-of-javascript-proxies-aa27c6d06bcb
來個【分享、點讚、在看】三連支持一下吧css特效第一季:https://blog.csdn.net/qq449245884/category_9873715.html
css特效第二季:https://blog.csdn.net/qq449245884/category_10212382.html
css特效第三季:https://blog.csdn.net/qq449245884/category_10791873.html