<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaScript代理的驚人力量

          共 5103字,需瀏覽 11分鐘

           ·

          2021-05-06 09:36

          今天我們要學習的是ECMAScript 6 Proxies。我們將在本文中涉及以下主題。

          • 什么是代理

          • 代理人在行動

          • 誰使用代理

          • 使用案例和實例

          • 資源簡介

          開始吧:)

          什么是代理

          正如MDN網(wǎng)站上所說。

          Proxy對象可以讓你為另一個對象創(chuàng)建一個代理,它可以攔截和重新定義該對象的基本操作。

          在解釋什么是Proxy的時候,說它可以創(chuàng)建一個Proxy,這有點搞笑。當然,他們并沒有說錯,但是我們可以簡化這個說法,讓它更加友好。

          Proxy對象使你能夠包裝目標對象 通過這樣可以攔截和重新定義該對象的基本操作。

          基本上,它的意思是說,我們要把一個對象,用Proxy包裹起來,這將允許我們創(chuàng)建一個 "隱藏 "的門,并控制所有對所需對象的訪問。

          一個小插曲,Proxy也是一種軟件設計模式,你一定要讀一讀(維基百科鏈接)。

          一個Proxy的創(chuàng)建有兩個參數(shù)。

          • target: 你想包裹的原始對象(proxy)

          • handler:定義哪些操作將被攔截,以及如何重新定義被攔截的操作的對象,也可以調(diào)用 "陷阱"。

          代碼

          1. const target = {

          2. message1: "hello",

          3. message2: "everyone"

          4. };


          5. const handler = {};


          6. const proxy = new Proxy(target, handler);

          大多數(shù)瀏覽器都支持代理功能,但也有一些老的瀏覽器不支持(當然是IE),你可以在這里查看完整的列表。google有一個代理的polyfill,但它不支持所有的代理功能。

          現(xiàn)在知道了什么是Proxies,想看看能用它做什么。

          代理人在行動

          讓我們想象一下,我們是一家銀行或一個憂心忡忡的女朋友。我們想知道每次銀行賬戶余額被訪問和被通知的時間。我們將使用最簡單的處理程序操作/trap: get

          1. const bankAccount = {

          2. balance: 2020,

          3. name: 'Georgy Glezer'

          4. };


          5. const handler = {

          6. get: function(target, prop, receiver) {

          7. if (prop === 'balance') {

          8. console.log(`Current Balance Of: ${target.name} Is: ${target.balance} `);

          9. }


          10. return target[prop];

          11. }

          12. };


          13. const wrappedBankAcount = new Proxy(bankAccount, handler);


          14. wrappedBankAcount.balance; // access to the balance


          15. // OUTPUT:

          16. // Current Balance Of: Georgy Glezer Is: 2020

          17. // 2020

          在上面的例子中,我們有一個銀行賬戶對象,里面有我的名字和2020的余額。

          這次的處理者對象是實現(xiàn)get操作/trap,它接收一個有3個參數(shù)的函數(shù)和get的返回值。

          • target: 被訪問的對象(我們封裝的對象)。

          • prop:被訪問的對象(我們封裝的對象)。在我們的例子中被訪問的屬性,這里是 "balance"。

          • receiver:接收者。可以是代理,也可以是繼承自代理的對象。

          我們定義了一個條件,如果被訪問的屬性是 "余額",我們將通知(log)余額和當前用戶名,并返回 "余額 "屬性。

          從輸出中可以看到,一旦 "balance "屬性被訪問,我們就通過使用Proxy和設置get操作/陷阱,很容易地通知(log)了這次訪問。

          繼續(xù)我們銀行的想法,要求每次有人從銀行賬戶中取錢,我們都要得到通知。而另一個約束條件是,銀行不允許出現(xiàn)負余額。為了達到這個目的,我們這次要使用設置處理程序/陷阱。

          1. const bankAccount = {

          2. balance: 2020,

          3. name: 'Georgy Glezer'

          4. };


          5. const handler = {

          6. set: function (obj, prop, value) {

          7. console.log(`Current Balance: ${obj.balance}, New Balance: ${value}`);


          8. if (value < 0) {

          9. console.log(`We don't allow Negative Balance!`);

          10. return false;

          11. }

          12. obj[prop] = value;


          13. return true;

          14. }

          15. };


          16. const wrappedBankAcount = new Proxy(bankAccount, handler);


          17. wrappedBankAcount.balance -= 2000; // access to the balance

          18. console.log(wrappedBankAcount.balance);


          19. wrappedBankAcount.balance -= 50; // access to the balance

          20. console.log(wrappedBankAcount.balance);


          21. // OUTPUT:

          22. // Current Balance: 2020, New Balance: 20

          23. // 20

          24. // Current Balance: 20, New Balance: -30

          25. // We don't allow Negative Balance!

          26. // 20

          在上面的例子中,我們通知當前的余額和取款后的新余額,如果新的余額是負數(shù),我們也會通知并中止取款操作。

          我們使用的是set operator/trap,它是一個返回布爾值(true/false)的函數(shù),用來判斷更新操作是否成功。它接收以下參數(shù)。

          • target: 被訪問的對象(我們封裝的對象)。

          • prop.prop:被訪問的對象(我們封裝的對象)。在我們的例子中,被訪問的屬性是 "balance"。

          • 值。應該更新的新值。

          • receiver:接收器。賦值最初指向的對象。這通常是代理本身。但是set()處理程序也可以間接調(diào)用,通過原型鏈或其他各種方式。

          你可以看到,它和get真的很相似,但只是多接收了1個新值的參數(shù)。

          這2個操作符/陷阱是最常見的,如果你有興趣找到所有現(xiàn)有的操作符/陷阱,你可以在這里查看。

          誰使用代理

          許多流行的庫都使用了這種技術,例如。

          • MobX

          • Vue

          • 沉浸式

          還有更多......他們中的大多數(shù)人都利用了Proxies給我們帶來的驚人力量,并為我們提供了很棒的庫。

          使用案例和實例

          我們已經(jīng)看到,我們可以使用代理服務器來進行。

          • 登錄(通知銀行)

          • 驗證(阻止負值更新)

          緩存

          我們將再次使用get operator/trap,并將 "dollars "屬性添加到我們的對象中。在每次訪問 "dollars "屬性時,我們將計算我們的余額價值多少美元。因為計算可能是一個沉重的操作,我們希望盡可能多的Cache它。

          1. const bankAccount = {

          2. balance: 10,

          3. name: 'Georgy Glezer',

          4. get dollars() {

          5. console.log('Calculating Dollars');

          6. return this.balance *3.43008459;

          7. }

          8. };


          9. let cache = {

          10. currentBalance: null,

          11. currentValue: null

          12. };


          13. const handler = {

          14. get: function (obj, prop) {

          15. if (prop === 'dollars') {

          16. let value = cache.currentBalance !== obj.balance ? obj[prop] : cache.currentValue;


          17. cache.currentValue = value;

          18. cache.currentBalance = obj.balance;


          19. return value;

          20. }


          21. return obj[prop];

          22. }

          23. };


          24. const wrappedBankAcount = new Proxy(bankAccount, handler);


          25. console.log(wrappedBankAcount.dollars);

          26. console.log(wrappedBankAcount.dollars);

          27. console.log(wrappedBankAcount.dollars);

          28. console.log(wrappedBankAcount.dollars);


          29. // OUTPUT:

          30. // Calculating Dollars

          31. // 34.3008459

          32. // 34.3008459

          33. // 34.3008459

          34. // 34.3008459

          正如你在例子中所看到的,我們有一個緩存對象,它保存著當前的銀行余額和以美元為單位的余額價值。每次有人訪問 "dollar "屬性時,我們都會先進行計算,然后將其緩存起來。

          Dom操作

          我們想在每次余額發(fā)生變化時更新屏幕上的文字。我們將使用一個set操作符/trap,每次改變數(shù)值時,我們將更新屏幕上的DOM元素。

          1. const bankAccount = {

          2. balance: 2020,

          3. name: "Georgy Glezer",

          4. get text() {

          5. return `${this.name} Balance Is: ${this.balance}`;

          6. }

          7. };


          8. const objectWithDom = (object, domId) => {

          9. const handler = {

          10. set: function (obj, prop, value) {

          11. obj[prop] = value;


          12. document.getElementById(domId).innerHTML = obj.text;


          13. return true;

          14. }

          15. };


          16. return new Proxy(object, handler);

          17. };


          18. // create a dom element with id: bank-account

          19. const wrappedBankAccount = objectWithDom(bankAccount, "bank-account");


          20. wrappedBankAccount.balance = 26;

          21. wrappedBankAccount.balance = 100000;

          在這里,我們創(chuàng)建了一個輔助函數(shù),這樣我們就可以存儲DOM元素的ID,并在set operator/trap中添加了簡單的行來更新DOM元素。很簡單,對吧?讓我們看看結(jié)果:)

          概要

          綜上所述,我們了解了ECMAScript 6 Proxies,我們?nèi)绾问褂盟鼈儯约坝糜谑裁茨康摹T谖铱磥恚硎且粋€神奇的工具,你可以用它來做各種各樣的選擇,你只需要考慮什么是最適合你的:) 。

          資源

          • MDN Proxy

          • “Proxies are awesome” Brendan Eich presentation at JSConf

          • Proxy Design Pattern

          關于本文 譯者:飄飄 作者:@Georgy Glezer 原文:https://levelup.gitconnected.com/the-amazing-power-of-javascript-proxies-aa27c6d06bcb

          如果覺得這篇文章還不錯
          點擊下面卡片關注我
          來個【分享、點贊、在看】三連支持一下吧

             “分享、點贊在看” 支持一波  

          瀏覽 45
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月激情婷婷影音娱乐 | av搬运一区二区三区在线观看 | 成人免费看性爱大片密芽 | 欧美亚洲国产日韩 | 国产AV手机版 |