参考错误:初始化前无法访问“数学”

问题描述

今天我遇到了一个我以前从未见过的错误,而且,也没有关于此的相关 SO 帖子。

ReferenceError: 初始化前无法访问“Math”

我已尝试添加 IIFE,但仍然无法正常工作。 在我之前的 web dev 工作中,我从来不需要包含 math.js 或导入它,我一直认为它是提供的。在我上次尝试之前,它始终运行良好,在我的其他脚本中,我可以调用 Math.abs,Math.floor 等。

抱歉,我无法提供任何最低限度的工作示例,这是完整的错误报告。

未捕获的引用错误:初始化前无法访问“数学”


这是我试图运行的脚本:
// round to 2 decimal places
const rit = val => Math.round(val * 100) / 100;

function render_element(styles,el) {
  for (const [kk,vv] of Object.entries(styles)) {
    el.style[kk] = vv;
  }
}

class Clock{
    // unit: min
    static day(){
        return 1440;
    }

    constructor(str){
        var [h,min] = str.split(':');
        this.h = parseInt(h);
        this.min = parseInt(min);
    }

    concat(){
        return new Clock(this.parse());
    }

    // convert clock h,min to min
    minutes(){
        return this.h * 60 + this.min
    }

    // pass in a clock,return gap in minute
    gap(clock){
        return Math.abs(this.minutes() - clock.minutes());
    }

    gaplength(clock,h,min,length){
        return this.gap(clock) / (h * 60 + min) * length;
    }

    parse(){
        var h = this.h.toString();
        var min = this.min.toString();
        min = min.length == 1 ? min + '0' : min;
        return h + ':' + min;
    }

    add_h(h){
        if(this.h + h >= 24){
            this.h = this.h + h - 24;
        }else{
            this.h += h;
        }
    }

    add_min(min){
        if(this.min + min >= 60){
            this.add_h(1);
            this.min = this.min + min - 60;
        }else{
            this.min = this.min + min;
        }
    }
}

class Period{
    // pass in two clock object
    constructor(from_,to_){
        this.from_ = from_.concat();
        this.to_ = to_.concat();
    }

    concat(){
        return new Period(this.from_,this.to_);
    }

    gap(){
        return this.from_.gap(this.to_);
    }

    gaplength(h,length){
        return this.from_.gaplength(this.to_,length);
    }

    shift_min(min){
        this.from_.add_min(min);
        this.to_.add_min(min);
    }

    shift_h(h){
        this.from_.add_h(h);
        this.to_.add_h(h);
    }
}

class Subject{
    constructor(
        bg_url,name,course,teacher,start,// string,e.g. 12:45
        finish,color,){
        this.bg_url = 'img/' + bg_url;
        this.name = name;
        this.course = course;
        this.teacher = teacher;
        this.start = new Clock(start);
        this.finish = new Clock(finish);

        this.color = color;

        this.duration = new Period(this.start,this.finish);
        // percents
        this.left = rit(this.start.gaplength(new Clock('11:00'),7,100));
        this.width = rit(this.duration.gaplength(7,100));

        this.card_style = {
            position: 'relative',width: '20%',height: '20%',borderRadius: '20px',};

        this.card_content_style = {
            position: 'absolute',};

        this.h1_style = {
            width: '100%',height: '5%',fontSize: '1.2em',padding: '0 5px 5px 5px',};

        this.course_style = {
            width: '100%',textAlign: 'center',fontWeight: 'bold',};

        this.teacher_style = {
            width: '100%',fontStyle: 'italic',textAlign: 'right',};

        this.btn_wrapper_style = {
            position: 'absolute',top: '0',right: '0',width: '40%',height: '35%',zIndex: '100',display: 'flex',flexDirection: 'row',justifyContent: 'space-between',alignItems: 'center',};

        this.btn_style = {
            width: '45%',height: '45%',justifyContent: 'center',borderRadius: '10px',cursor: 'pointer',overflow: 'hidden',};

        this.modify_mouseenter_style = {
            background: 'gold',color: 'black',};

        this.modify_mouseleave_style = {
            background: 'orange',color: 'white',};

        this.remove_mouseenter_style = {
            background: 'pink',};

        this.remove_mouseleave_style = {
            background: 'orchid',};

        this.card_el = document.createElement('div');
        render_element(this.card_style,this.card_el);
        this.img_el = document.createElement('img');
        this.img_el.setAttribute('src',this.bg_url);
        this.img_el.style.opacity = 0.3;
        this.card_content_el = document.createElement('div');
        render_element(this.card_content_style,this.card_content_el)
        this.h1_el = document.createElement('h1');
        this.h1_el.innerHTML = this.name;
        render_element(this.h1_style,this.h1_el);
        this.hr_el = document.createElement('hr');
        this.hr_el.style.borderColor = this.color;
        this.hr_el.style.opacity = '0.5';
        this.course_el = document.createElement('p');
        this.course_el.innerHTML = this.course;
        render_element(this.course_style,this.course_el);
        this.teacher_el = document.createElement('p');
        this.teacher_el.innerHTML = this.teacher;
        render_element(this.teacher_style,this.teacher_el);
        this.btn_wrapper_el = document.createElement('div');
        render_element(this.btn_wrapper_style,this.btn_wrapper_el);
        this.btn_modify_el = document.createElement('div');
        this.btn_modify_el.innerHTML = 'modify';
        render_element(this.btn_style,this.btn_modify_el);
        this.btn_remove_el = document.createElement('div');
        this.btn_remove_el.innerHTML = 'remove';
        render_element(this.btn_style,this.btn_remove_el);
        
        this.card_el.appendChild(this.img_el);
        this.card_el.appendChild(this.card_content_el);
        this.card_content_el.appendChild(this.h1_el);
        this.card_content_el.appendChild(this.hr_el);
        this.card_content_el.appendChild(this.course_el);
        this.card_content_el.appendChild(this.teacher_el);
        this.card_el.appendChild(this.btn_wrapper_el);
        this.btn_wrapper_el.appendChild(this.btn_modify_el);
        this.btn_wrapper_el.appendChild(this.btn_remove_el);

        this.becomeChildOf = this.becomeChildOf.bind(this);
        this.modifyMouseEnter = this.modifyMouseEnter.bind(this);
        this.modifyMouseLeave = this.modifyMouseLeave.bind(this);
        this.removeMouseEnter = this.removeMouseEnter.bind(this);
        this.removeMouseLeave = this.removeMouseLeave.bind(this);
    
        this.btn_modify_el.addEventListener('mouseenter',this.modifyMouseEnter);
        this.btn_modify_el.addEventListener('mouseleave',this.modifyMouseLeave);
        this.btn_remove_el.addEventListener('mouseenter',this.removeMouseEnter);
        this.btn_remove_el.addEventListener('mouseleave',this.removeMouseLeave);
    }

    becomeChildOf(parent_el){
        this.parent_el = parent_el;
        this.parent_el.appendChild(this.card);
    }

    modifyMouseEnter(){
        render_element(this.modify_mouseenter_style,this.btn_modify_el);
    }

    modifyMouseLeave(){
        render_element(this.modify_mouseleave_style,this.btn_modify_el);
    }

    removeMouseEnter(){
        render_element(this.remove_mouseenter_style,this.btn_remove_el);
    }

    removeMouseLeave(){
        render_element(this.remove_mouseleave_style,this.btn_remove_el);
    }
}

class VisualArts extends Subject{
    constructor(
        course,finish,){
        super(
            'visual-arts.jpg','red',)
    }
}

new VisualArts(
    'Visual Arts','James Collin','11:00','11:45',)

错误发生在:

    // pass in a clock,return gap in minute
    gap(clock){
        return Math.abs(this.minutes() - clock.minutes());
    }

更新

要运行整个脚本,我可以:

console.log(Math.abs(-1));

但是在上面的脚本中,我做不到:

    gap(clock){
        var min = this.minutes() - clock.minutes();
        console.log(Math.abs(-1));
        // ReferenceError: Cannot access 'Math' before initialization
        return Math.abs(min);
    }

我真的不知道为什么会发生这种情况

此外,为了测试脚本,您不需要 html 或 css。

非常感谢您的建议。

解决方法

我认为这可能是问题的始作俑者:-

class VisualArts extends Subject{
    constructor(
        course,teacher,start,finish,){
        super(
            'visual-arts.jpg',course,'red',)
    }
}

您是 super 需要 7 个参数,因为 Subject 构造函数需要 7。当您传递它们 6 时,您将弄乱分配给 { 的值的顺序{1}} 和 start 负责构建您的 finish 对象。他们没有得到您想要的 Clock11.00