在将项写入会话存储时,我希望记录堆栈跟踪。
这对于sessionStorage.setItem('hello', 'world')来说是很好的:
const ogSessionStorageSetItem = sessionStorage.setItem;
sessionStorage.setItem = async function(key, value) {
console.log('Wrote', key);
console.trace();
ogSessionStorageSetItem.apply(this, arguments);
};但是它在做sessionStorage.hello = 'world'或sessionStorage['hello'] = 'world'时不起作用。
我试过用代理:
const handler = {
get: function(target, name) {
console.log('get', name)
console.trace()
return target[name];
},
set: function(target, name, value) {
console.log('set', name)
console.trace()
target[name] = value;
},
};
const proxy = new Proxy(sessionStorage, handler);
Object.defineProperty(window, "sessionStorage", {
value: proxy,
configurable: true,
enumerable: true,
writable: false
});它适用于点和[],但不适用于setItem。
怎么才能让他们俩一起工作呢?
更新2:
尝试过的解决方案(@Polywhirl先生),现在我得到了一个副作用:sessionStorage.setItem = function...认为它必须将键/值: setItem =>函数定义保存到会话存储中。
const sessionStorageProxy = new Proxy(sessionStorage, {
get(target, name, receiver) {
console.log('get', name)
console.log(receiver, target)
console.trace()
return Reflect.get(target, name, receiver);
},
set(target, name, value, receiver) {
console.log('set', name)
console.trace()
return Reflect.set(target, name, value, receiver);
}
});
Object.defineProperty(window, "sessionStorage", {
value: sessionStorageProxy,
configurable: true,
enumerable: true,
writable: false
});
const ogSessionStorageSetItem = sessionStorage.setItem;
// this below is acting like sessionStorage.super = 'cool'
sessionStorage.setItem = async function(key, value) {
console.log('Wrote', key);
console.trace();
ogSessionStorageSetItem.apply(this, arguments);
};

发布于 2020-10-04 04:52:48
正如@Mr Polywhirl所提到的,您可以使用Proxy包装目标对象。对于简单的对象,它工作得很好,但是一旦开始使用复杂的对象,它很快就会变得很混乱。
无论如何,根据您更新的问题,在您的get处理程序中,您将以value的形式返回所有内容,但是对于可调用的值(函数),您需要发送另一个在代理中配置了apply方法的代理,或者在原始对象上调用函数而不是代理:
get(target, name, receiver) {
const value = Reflect.get(target, name, receiver);
return typeof value === 'function' ?
value.bind(target) :
value;
}让我们看一看应用了更改的代码:
// we are overriding this before configuring proxy
// setting setItem afterwards will put this method on proxy itself and not on sessionStorage object
// override session storage
const ogSessionStorageSetItem = sessionStorage.setItem;
sessionStorage.setItem = async function(key, value) {
console.log('Wrote', key);
console.trace();
ogSessionStorageSetItem.apply(this, arguments);
};
// create proxy
const sessionStorageProxy = new Proxy(sessionStorage, {
get(target, name, receiver) {
const value = Reflect.get(target, name, receiver);
return typeof value === 'function' ?
value.bind(target) :
value;
},
set(target, name, value, receiver) {
if (name === 'setItem') {
return false;
}
return Reflect.set(target, name, value, receiver);
}
});
Object.defineProperty(window, "sessionStorage", {
value: sessionStorageProxy,
configurable: true,
enumerable: true,
writable: false
});
sessionStorage.key1 = "value1";
sessionStorage["key2"] = "value2";
sessionStorage.setItem('key3', 'value3');
console.log(sessionStorage.key1);
console.log(sessionStorage["key2"]);
console.log(sessionStorage.getItem("key3"));
你可能会发现这篇文章有用,干杯!
发布于 2020-10-01 17:52:54
您可以将sessionStorage封装在Proxy中。这让你可以钩到策划人。
const sessionStorageProxy = new Proxy(window.sessionStorage, {
get(target, name, reciever) {
return Reflect.get(target, name, reciever);
},
set(target, name, value, receiver) {
console.log('Wrote', name);
return Reflect.set(target, name, value, receiver);
}
});
sessionStorage.setItem = async function(key, value) {
console.log('Wrote', key);
console.trace();
sessionStorageProxy.apply(this, arguments);
};
sessionStorage.setItem('hello', 'world');
console.log(sessionStorage.getItem('hello')); // world
sessionStorageProxy.hello = 'world2';
console.log(sessionStorageProxy.hello); // world2https://stackoverflow.com/questions/64160396
复制相似问题