使用动态import()时出现‘object is not extensible’错误的解决问询
问题描述
通过动态import()导入JavaScript模块时,Chrome浏览器抛出以下错误:
script.js:2 Uncaught (in promise) TypeError: Cannot add property whatever, object is not extensible
at Module.myFunction (script.js:2:19)
at module.html:12:33
相关代码如下:
HTML文件代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"><title>Module</title><style>:root { background: #545454; }</style> <script> window.addEventListener('load', e => { import('./script.js').then(async module => { const fn = await module.myFunction(); fn.whatever(); }); }); </script> </head> <body></body> </html>
script.js文件代码
export async function myFunction() { this.whatever = function () { console.log('Ok'); }; return this; }
问题原因
在ES模块中,顶层作用域的this指向模块的命名空间对象,这个对象被JS引擎默认设置为不可扩展(non-extensible)。当你直接调用module.myFunction()时,函数内部的this绑定到了这个不可扩展的命名空间对象上,无法给它添加新属性,因此触发报错。
解决方法
核心思路是避免修改不可扩展的模块命名空间对象,改用可扩展的自定义对象,以下是几种可行方案:
方法一:创建新对象并返回
在函数内部生成普通空对象,添加方法后返回:
export async function myFunction() { const result = {}; result.whatever = function () { console.log('Ok'); }; return result; }
方法二:用对象字面量简化写法
直接通过对象字面量定义并返回,代码更简洁:
export async function myFunction() { return { whatever() { console.log('Ok'); } }; }
方法三:使用类返回实例
如果后续需要扩展更多方法,类的写法更便于维护:
export async function myFunction() { class MyModule { whatever() { console.log('Ok'); } } return new MyModule(); }
以上三种方案都能正常运行,调用端代码无需修改。
内容的提问来源于stack exchange,提问作者goodUser
相关产品推荐
相关产品推荐

