proxy get方法怎么判断是正常读属性或函数调用?
想把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'));