es6代理proxy对象介绍

什么是代理?

代理类,用来进行事物不想或不能进行的其他操作,比如当你对数据库进行操作时,代理可以在你对数据库操作完后,记录下你所进行的操作。

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

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

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

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

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

const handler = {};

const proxt = new Proxy(target, handler)

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

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

现在假设有一个银行账号,有名字和余额属性,每次放问余额时我们想知道被访问的时间。

const bankAccount = {
	balance: 2021,
	name: 'feng'
}

const handler = {
	get: function (target, prop) {
		if (prop === 'balance') {
			console.log(`当前余额: ${target.balance}`)
		}
		
		return target[prop]
	}
}

const bankProxy = new Proxy(bankAccount, handler)
bankProxy.balance // 当前余额2021

在上面的例子中,我们有一个银行账户对象,里面有我的名字和2021的余额。

这次的处理者对象是实现get操作/trap,它接收一个有2个参数的函数和get的返回值。

  • target: 被访问的对象(我们封装的对象)。
  • prop:被访问的对象(我们封装的对象)。在我们的例子中被访问的属性,这里是 “balance”。

我们定义了一个条件,如果被访问的属性是 “余额”,我们将通知(log)余额和当前用户名,并返回 "余额 "属性。

从输出中可以看到,一旦 "balance "属性被访问,我们就通过使用Proxy和设置get操作/陷阱,很容易地通知(log)了这次访问。

继续我们银行的想法,要求每次有人从银行账户中取钱,我们都要得到通知。而另一个约束条件是,银行不允许出现负余额。为了达到这个目的,我们这次要使用设置处理程序/陷阱。

const bankAccount = {
	balance: 2021,
	name: 'feng'
}

const handler = {
	set: function (target, prop, value) {
		if (prop === 'balance') {
			if (value < 0) {
				console.log('余额低于取出金额')
				return false
			}
			target[prop] = value
			console.log(`已取出${value}`)
			return true
		}
	}
}

const bankProxy = new Proxy(bankAccount, handler)
bankProxy.balance -= 2000 // 取出2000
bankProxy.balance -= 22 // 余额低于取出金额

在上面的例子中,我们通知当前的余额和取款后的新余额,如果新的余额是负数,我们也会通知并中止取款操作。

我们使用的是set operator/trap,它是一个返回布尔值(true/false)的函数,用来判断更新操作是否成功。它接收以下参数。

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

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

Dom操作

我们想在每次余额发生变化时更新屏幕上的文字。我们将使用一个set操作符/trap,每次改变数值时,我们将更新屏幕上的DOM元素。

const bankAccount = { 
	balance: 2020,
	name: "feng",
	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元素。很简单,对吧?让我们看看结果:)

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值