重写localStorage.setItem出现Illegal invocation非法调用错误如何解决?
问题原因
你遇到的Illegal Invocation报错由两个错误写法共同导致:
- 你使用箭头函数重写
Storage.prototype.setItem,箭头函数没有独立的this上下文,无法指向实际调用方法的localStorage/sessionStorage实例。 - 原生的
setItem是浏览器提供的宿主API,要求调用时this必须绑定到合法的Storage实例,你直接调用originalFunction()时,内部this指向的是全局window(严格模式下为undefined),不符合宿主API的执行要求,因此抛出非法调用错误。
修复方案
把箭头函数替换为普通函数,调用原始方法时手动绑定当前执行上下文即可,修复后的代码如下:
let originalFunction = window.Storage.prototype.setItem; window.Storage.prototype.setItem = function(keyName, keyValue) { console.log("Override worked ! "); // 这里直接用this.getItem,不需要硬写localStorage,兼容sessionStorage的调用 let currentState = this.getItem("disableStorage"); if (currentState === null || keyName === "disableStorage") { // 绑定当前Storage实例作为上下文调用原始方法 originalFunction.call(this, keyName, keyValue); } return; } localStorage.setItem("test", "blah");
如果你只需要重写localStorage的setItem,不需要影响sessionStorage,也可以直接修改实例方法而不用动原型,写法如下:
const originalSetItem = localStorage.setItem; localStorage.setItem = function(key, value) { const disabled = localStorage.getItem("disableStorage"); if (disabled === null || key === "disableStorage") { originalSetItem.call(this, key, value); } }
内容的提问来源于stack exchange,提问作者polypode
相关产品推荐
相关产品推荐

