【发布时间】:2021-02-13 14:02:31
【问题描述】:
今天我遇到了一个我以前从未见过的错误,而且没有关于此的相关 SO 帖子。
ReferenceError:初始化前无法访问“数学”
我已尝试添加 IIFE,但仍然无法正常工作。
在我之前的 web 开发工作中,我从来不需要包含 math.js 或导入它,我一直认为它是提供的。在我最后一次尝试之前,它总是可以正常工作,在我的其他脚本中,我可以调用 Math.abs, Math.floor 等等。
抱歉,我无法提供任何最低限度的工作示例,这是完整的错误报告。
未捕获的 ReferenceError:在初始化之前无法访问“数学”
这是我要运行的脚本:
// 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, min, length){
return this.from_.gaplength(this.to_, h, min, 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, 0, 100));
this.width = rit(this.duration.gaplength(7, 0, 100));
this.card_style = {
position: 'relative',
width: '20%',
height: '20%',
borderRadius: '20px',
};
this.card_content_style = {
position: 'absolute',
width: '20%',
height: '20%',
borderRadius: '20px',
};
this.h1_style = {
width: '100%',
height: '5%',
fontSize: '1.2em',
padding: '0 5px 5px 5px',
};
this.course_style = {
width: '100%',
height: '5%',
textAlign: 'center',
fontSize: '1.2em',
fontWeight: 'bold',
};
this.teacher_style = {
width: '100%',
height: '5%',
fontSize: '1.2em',
fontStyle: 'italic',
textAlign: 'right',
};
this.btn_wrapper_style = {
position: 'absolute',
top: '0',
right: '0',
width: '40%',
height: '35%',
borderRadius: '20px',
zIndex: '100',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
};
this.btn_style = {
width: '45%',
height: '45%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '10px',
fontWeight: 'bold',
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',
color: 'black',
};
this.remove_mouseleave_style = {
background: 'orchid',
color: 'white',
};
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,
teacher,
start,
finish,
){
super(
'visual-arts.jpg',
course,
teacher,
start,
finish,
'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。
非常感谢您的建议。
【问题讨论】:
-
什么代码导致了这个错误?
-
这不是一个最小的例子。将其分解为尽可能小的示例时,您可能会自己找到解决方案。
-
这里留个言,当在父初始化器中调用特定对象的方法时,记得要
bind函数,否则,this会被传入函数.从结构上讲,this在super()完成之前是不允许的。因此,引用错误将作为this传递给函数。在这种情况下,很难找出哪一部分出了问题。
标签: javascript math.js