使用JS类表达式时报错Cannot access class before initialization如何解决
问题根因
这个报错是JavaScript自动分号插入(ASI)规则导致的语法解析歧义:
你定义类表达式的语句末尾没有显式写分号,解析器会把紧随其后的自执行函数的括号,识别为前面类表达式的调用运算符,你的代码会被解析为如下逻辑:
// 解析器错误的拼接逻辑 const ShapeOverlays = class { // 你的类代码 }( // 把后面的自执行函数当做类的参数执行 (function() { const elmHamburger = document.querySelector('.hamburger'); // ... 省略自执行函数代码 // 这里访问ShapeOverlays时,外层的赋值还没完成,触发暂存死区报错 const overlay = new ShapeOverlays(elmOverlay); }()) );
此时自执行函数执行时,ShapeOverlays还处于变量的暂存死区,没有完成赋值初始化,就会抛出你遇到的引用错误。
修复方案
有两种常用的修复方式:
- 方案1:在类表达式赋值语句末尾加显式分号,强制拆分两个独立语句
const ShapeOverlays = class { // 你的类代码 }; // 这里加个分号即可 (function() { // 你的自执行函数代码 }()); - 方案2:改用类声明的写法定义类,从根源避免ASI歧义
// 类声明写法,不需要赋值操作,不会和后面的自执行函数产生解析冲突 class ShapeOverlays { constructor(elm) { this.elm = elm; this.path = elm.querySelectorAll('path'); this.numPoints = 4; this.duration = 1000; this.delayPointsArray = []; this.delayPointsMax = 0; this.delayPerPath = 60; this.timeStart = Date.now(); this.isOpened = false; this.isAnimating = false; } } (function() { // 你的自执行函数代码 }());
另外建议养成良好的编码习惯:要么所有语句末尾都显式加分号,要么遇到以括号、方括号、模板字符串开头的语句时,在语句开头补一个防御性分号,避免同类的ASI解析问题。
内容的提问来源于stack exchange,提问作者user3714932
相关产品推荐
相关产品推荐

