proxy get方法怎么判断是正常读属性或函数调用?
发布于 3 年前 作者 xinggsf 1808 次浏览 来自 问答

想把cookie操作用proxy封装,原代码如下:

const cookie = (name, value, options = {}) => {
	if (value !== void 0) {
		let s = name + '=' + encodeURIComponent(value);
		if (options.expires && (typeof options.expires == 'number' ||
			options.expires.toUTCString))
		{
			let date;
			if (typeof options.expires == 'number') {
				date = new Date();
				date.setTime(options.expires * 24 * 3600000 + date.getTime());
			} else {
				date = options.expires;
			}
			s += '; expires=' + date.toUTCString();
		}
		//options: expires,path,domain,secure
		delete options.expires;
		for (const k in options) s += '; ' + k + '=' + options[k];
		document.cookie = s;
	} else {
		let s = ''+ document.cookie;
		const head = name + '=';
		s = s.split(/\s*;\s*/).find(k => k.startsWith(head));
		return s && decodeURIComponent(s.slice(name.length + 1));
	}
};

封装后代码,重点看注释行:

const cookie = new Proxy({}, {
	get(target, name) {
		// 正常读取属性, name永远为字符串
		// if (typeof name == 'string') { //如何判断?
			// let s = ''+ document.cookie;
			// const head = name + '=';
			// s = s.split(/\s*;\s*/).find(k => k.startsWith(head));
			// return s && decodeURIComponent(s.slice(name.length + 1));			
		// }
		return function (value, options = {}) {
			if (value == null) {
				value = '';
				options.expires = -1;
			}
			let s = name + '=' + encodeURIComponent(value);
		    options.expires = options.expires || 6;
			if (options.expires && (typeof options.expires == 'number' ||
				options.expires.toUTCString))
			{
				let date;
				if (typeof options.expires == 'number') {
					date = new Date();
					date.setTime(options.expires * 24 * 3600000 + date.getTime());
				} else {
					date = options.expires;
				}
				s += '; expires=' + date.toUTCString();
			}
			delete options.expires;
			for (const k in options) s += '; ' + k + '=' + options[k];
			document.cookie = s;
		}
	}
});
// cookie.cna; //正常读属性
cookie.cna('dfafdda'); //写cookie
3 回复

问题应使用正确的表达方式,我猜你说的“正常”是指“读取属性”
“函数调用”也是读取属性,也不是“非正常”

obj.go()

这类代码,其实是先读取了 obj 的 go 属性,再把这个属性的值当作函数来执行(或者称为“调用”)

建议:贴代码是为了让问题更容易被人理解;但贴太多代码,会让问题更“麻烦”
并未回答你的问题,抱歉

@daGaiGuanYu 超过一屏代码的问题一般懒得看, 说明提问人自己都不知道自己在问什么

看来无解,用了个变通办法,不过代码就不太直观

const noopFn = () => {};
const cookie = new Proxy(noopFn, {
	get(target, name) {
		return function (value, options = {}) {// 写入cookie
			let s = name + '=' + encodeURIComponent(value);

			options.expires = options.expires || 6;
			if (options.expires && (typeof options.expires == 'number' ||
				options.expires.toUTCString))
			{
				let date;
				if (typeof options.expires == 'number') {
					date = new Date();
					date.setTime(options.expires * 24 * 3600000 + date.getTime());
				} else {
					date = options.expires;
				}
				s += '; expires=' + date.toUTCString();
			}
			delete options.expires;
			for (const k in options) s += '; ' + k + '=' + options[k];
			document.cookie = s;
		}
	},
	apply(target, ctx, args) { // 读取cookie
		let s = ''+ document.cookie;
		const head = args[0] + '=';
		s = s.split(/\s*;\s*/).find(k => k.startsWith(head));
		return s && decodeURIComponent(s.slice(head.length));
	},
	deleteProperty(target, name, descriptor) {// 删除cookie
		document.cookie = name + '=; domain=*; expires='+ new Date().toUTCString();
		return true;
	}
});
// 测试
delete cookie.cna;
cookie.testxx('fafweff');
log(cookie('cna'), cookie('testxx'));
回到顶部