js Proxy代理惊人力量

AI 概述
什么是代理代理人在行动谁使用代理使用案例和实例缓存Dom 操作总结 今天我们要学习的是 ECMAScript 6 Proxies。我们将在本文中涉及以下主题。 什么是代理 代理人在行动 谁使用代理 使用案例和实例 资源简介 什么是代理 正如 MDN 网站上所说。、 Proxy 对象可以让你为另一个对象创建一个代理,它可以...
目录
文章目录隐藏
  1. 什么是代理
  2. 代理人在行动
  3. 谁使用代理
  4. 使用案例和实例
  5. Dom 操作
  6. 总结

js Proxy 代理惊人力量

今天我们要学习的是 ECMAScript 6 Proxies。我们将在本文中涉及以下主题。

  • 什么是代理
  • 代理人在行动
  • 谁使用代理
  • 使用案例和实例
  • 资源简介

什么是代理

正如 MDN 网站上所说。、

Proxy 对象可以让你为另一个对象创建一个代理,它可以拦截和重新定义该对象的基本操作。

在解释什么是 Proxy 的时候,说它可以创建一个 Proxy,这有点搞笑。当然,他们并没有说错,但是我们可以简化这个说法,让它更加友好。

Proxy 对象使你能够包装目标对象 通过这样可以拦截和重新定义该对象的基本操作。

基本上,它的意思是说,我们要把一个对象,用 Proxy 包裹起来,这将允许我们创建一个 “隐藏 “的门,并控制所有对所需对象的访问。

一个小插曲,Proxy 也是一种软件设计模式,你一定要读一读(维基百科链接)。

一个 Proxy 的创建有两个参数。

  • target: 你想包裹的原始对象(proxy)
  • handler:定义哪些操作将被拦截,以及如何重新定义被拦截的操作的对象,也可以调用 “陷阱”。

代码

const target = {
  message1: "hello",
  message2: "everyone"};

const handler = {};

const proxy = new Proxy(target, handler);

大多数浏览器都支持代理功能,但也有一些老的浏览器不支持(当然是 IE),你可以在这里查看完整的列表。google 有一个代理的polyfill,但它不支持所有的代理功能。

现在知道了什么是 Proxies,想看看能用它做什么。

代理人在行动

让我们想象一下,我们是一家银行或一个忧心忡忡的女朋友。我们想知道每次银行账户余额被访问和被通知的时间。我们将使用最简单的处理程序操作

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 操作,它接收一个有 3 个参数的函数和 get 的返回值。

  • target: 被访问的对象(我们封装的对象)。
  • prop:被访问的对象(我们封装的对象)。在我们的例子中被访问的属性,这里是 “balance”。
  • receiver:接收者。可以是代理,也可以是继承自代理的对象。

我们定义了一个条件,如果被访问的属性是 “余额”,我们将通知(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)的函数,用来判断更新操作是否成功。它接收以下参数。

  • target: 被访问的对象(我们封装的对象)。
  • prop.prop:被访问的对象(我们封装的对象)。在我们的例子中,被访问的属性是 “balance”。
  • 值。应该更新的新值。
  • receiver:接收器。赋值最初指向的对象。这通常是代理本身。但是 set()处理程序也可以间接调用,通过原型链或其他各种方式。

你可以看到,它和 get 真的很相似,但只是多接收了 1 个新值的参数。

这 2 个操作符/陷阱是最常见的,如果你有兴趣找到所有现有的操作符/陷阱,你可以在这里查看。

谁使用代理

许多流行的库都使用了这种技术,例如。

  • MobX
  • Vue
  • 沉浸式

还有更多……他们中的大多数人都利用了 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,我们如何使用它们,以及用于什么目的。在我看来,代理是一个神奇的工具,你可以用它来做各种各样的选择,你只需要考虑什么是最适合你的 。

以上关于js Proxy代理惊人力量的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » js Proxy代理惊人力量

发表回复