JavaScript Proxy在实际工作中的一些应用

20 阅读1分钟

前言

Proxy,我之前文章中有写过,今天简单介绍几个工作中可以使用的案例。希望对大家有帮助,需要的时候可以使用,但是不提倡乱用。

Proxy 处理器get和set的介绍

//movie is a target
const movie = {
	name: "Pulp Fiction",
	director: "Quentin Tarantino"
};

//this is a handler
const handler = {
	//get is a trap
	get: (target, prop) => {
		if (prop === 'director') {
			return 'God'
		}
		return target[prop]
	},

	set: function (target, prop, value) {
		if (prop === 'actor') {
			target[prop] = 'John Travolta'
		} else {
			target[prop] = value
		}
	}
};

const movieProxy = new Proxy(movie, handler);

console.log(movieProxy.director); //God

movieProxy.actor = "Tim Roth";
movieProxy.actress = "Uma Thurman";

console.log(movieProxy.actor); //John Travolta
console.log(movieProxy.actress); //Uma Thurman

应用一 验证属性赋值

const handler = {
	set: function (target, prop, value) {
		const houses = ['Stark', 'Lannister'];
		if (prop === 'house' && !(houses.includes(value))) {
			throw new Error(`House ${value} does not belong to allowed ${houses}`)
		}
		target[prop] = value
	}
};

const gotCharacter = new Proxy({}, handler);

gotCharacter.name = "Jamie";
gotCharacter.house = "Lannister";

console.log(gotCharacter);

gotCharacter.name = "Oberyn";
gotCharacter.house = "Martell";

应用二 根据定义和状态实现功能,例如发送邮件

const sendEmail = () => {
	console.log("haorooms test status 是complete 的发邮件")
};


const handler = {
	set: function (target, prop, value) {
		if (prop === 'status' && value === 'complete') {
			sendEmail()
		}
		target[prop] = value
	}
};

const tasks = new Proxy({}, handler);

tasks.status = "complete";

应用三 设置数据缓存和超时

const cacheTarget = (target, ttl = 60) => {
	const CREATED_AT = Date.now();
	const isExpired = () => (Date.now() - CREATED_AT) > (ttl * 1000);
	const handler = {
		get: (target, prop) => isExpired() ? undefined : target[prop]
	};
	return new Proxy(target, handler)
};

const cache = cacheTarget({age: 25}, 5);

console.log(cache.age);

setTimeout(() => {
	console.log(cache.age)
}, 6 * 1000);

结果:

25
undefined

也就是在5秒之内可以返回,超时不返回。

缺点

虽然Proxy具备一些很神奇的功能, 但在使用时仍然具有一些不得不小心应对的限制:

性能会受到显著的影响. 在注重性能的代码中应该避免对Proxy的使用

没有办法区分判断一个对象是一个Proxy的对象或者是target的对象

Proxy可能会导致代码在可读性上面出现问题