代理(proxy)

1.代理的原理
var p=new Proxy(target,handler);

target 目标对象
handler 一个对象,其属性是执行操作的行为函数

const a = { name: "liu" }; ⇽--- emperor是目标对象
const b = new Proxy(a, { ⇽--- 通过Proxy构造器创建代理,传入对象emperor,以及包含get与set方的对象,用于处理对象属性的读写操作
	get: (target, key) => {
	report("Reading " + key + " through a proxy");
	return key in target ? target[key]
	: "Don't bother the a!"
	},
	set: (target, key, value) => {
	report("Writing " + key + " through a proxy");
	target[key] = value;
	}
});
assert(a.name === "Komei", "The a's name is Komei");

assert(b.name === "Komei","We can get the name property through a proxy"); ⇽--- 分别通过目标对象和代理对象访问name属性

assert(a.nickname === undefined,"The a doesn’t have a nickname "); ⇽--- 直接访问目标对象上不存在的nickname属性将返回undefined

assert(b.nickname === "Don't bother the a!", "The proxy jumps in when we make inproper requests");⇽---通过代理对象访问时,将会检测到nickname属性不存在,并因此返回警告

b.nickname = "Tenno";

assert(a.nickname === "Tenno","The a now has a nickname");

assert(b.nickname === "Tenno","The nickname is also accessible through the proxy"); ⇽--- 通过代理对象添加nickname属性后,分别通过目标对象和代理对象均可访问nickname属性
2.使用代理检测性能
function isPrime(number){
	if(number < 2) { return false; }
		for(let i = 2; i < number; i++) {
		if(number % i === 0) { return false; }
	} ⇽--- 定义isPrime函数的简单实现
	return true;
}
isPrime = new Proxy(isPrime, {        ⇽--- 使用代理包装isPrime方法
	apply: (target, thisArg, args) => {    ⇽--- 定义apply方法,当代理对象作为函数被调用时将会触发该apply方法的执行
		console.time("isPrime");             ⇽--- 启动一个计时器,记录isPrime函数执行的起
		始时间
		const result = target.apply(thisArg, args);       ⇽--- 调用目标函数
		console.timeEnd("isPrime");                   ⇽--- 停止计时器的执行并输出结果
		return result;
	}
});
isPrime(1299827); ⇽--- 同调用原始方法一样,调用isPrime方法

使用isPrime函数作为代理的目标对象。同时,添加apply方法,当调用isPrime函数时就会调用apply方法。与之前的示例类似,我们将新创建的代理对象赋值给isPrime标识符。这样,我们无需修改isPrime函数内部代码,就可以调用apply方法实现isPrime函数的性能评估,程序代码的其余部分可以完全无视些变化。

3.使用代理实现负数组索引

通常直接访问数组最后几位元素没有那么优雅,相比于Python的负数组索引,JavaScript并没有这么方便,现在我们可以通过代理实现负数组索引,优雅的访问数组

	const ninjas = ['a', 'b', 'c'];
	
	console.log(ninjas[-2]);//js不支持数组负索引
	console.log(ninjas.slice(-1));
	
	function createArray(array) {
	  if (!Array.isArray(array)) {
	    throw new TypeError('不是数组,报错')
	  }
	  return new Proxy(array,{
	    get(target,key){
	      key=+key;
	      return target[key < 0 ? target.length + key : key];
	    },
	    set(target, key, value) {
	      key=+key;
	      return target[key<0?target.length+key:key]=value
	    }
	  })
	}
	
	const arr = ['a', 'b', 'c', 'd'];
	const proxyArr = createArray(arr);
	console.log(proxyArr[-2]);
4.代理的性能消耗

事实上,我们所有的操作都通过代理添加了一个间接层,使我们能够实现所有这些很酷的特性,但与此同时它引入了大量的额外的处理,会影响性能。
所以代理效率不高,所以在需要执行多次的代码中需要谨慎使用。建议进行性能测试。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值