我得到"未捕获的TypeError:this.time_to_x不是函数"将一些开源ES5代码合并到我的ES6 Class中时。这是课程(我已经删除了一些批量,但大多数必要的东西都在那里)。假设调用Diamond()。这一行得到错误:x = this.time_to_x(frame.time);
为什么time_to_x()不被视为函数?
export default class TimelinePanel {
constructor(ctx) {
this.ctx = ctx;
this.ctx_wrap = ctx;
}
create (ctx) {
this.rect({ctx, x: 20, y: 15, width: 130, height: 10}); // ***
this.drawLayerContents();
}
Diamond(frame, y) {
var x, y2;
x = this.time_to_x(frame.time);
y2 = y + LINE_HEIGHT * 0.5 - DIAMOND_SIZE / 2;
var self = this;
var isOver = false;
this.path = function() {
this.ctx_wrap
.beginPath()
.moveTo(x, y2)
.lineTo(x + DIAMOND_SIZE / 2, y2 + DIAMOND_SIZE / 2)
.lineTo(x, y2 + DIAMOND_SIZE)
.lineTo(x - DIAMOND_SIZE / 2, y2 + DIAMOND_SIZE / 2)
.closePath();
};
}
drawLayerContents() {
// ...
for (i = 0; i < il; i++) {
// ...
for (j = 0; j < values.length; j++) {
// Dimonds
frame = values[j];
renderItems.push(new this.Diamond(frame, y));
}
}
}
y_to_track(y) {
if (y - MARKER_TRACK_HEIGHT < 0) return -1;
return (y - MARKER_TRACK_HEIGHT + scrollTop) / LINE_HEIGHT | 0;
}
x_to_time(x) {
var units = time_scale / tickMark3;
return frame_start + ((x - LEFT_GUTTER) / units | 0) / tickMark3;
}
time_to_x(s) {
var ds = s - frame_start;
ds *= time_scale;
ds += LEFT_GUTTER;
return ds;
}
}
答案 0 :(得分:2)
因为你拥有它的方式它假设time_to_x
来自闭合,而不是来自this
。在this
中没有这样的函数,因此this.time_to_x
名称返回undefined
,这实际上不是函数。
我建议像这样:
将var self = this;
放在类中但在Diamond
方法之外。
然后在self.time_to_x()
内拨打Diamond
。
答案 1 :(得分:2)
当您执行this.Diamond
时,您正在创建new this.Diamond(frame, y)
类的实例。因此,在函数内部,this
是这个新实例,而不是最初创建它的TimelinePanel
实例。因此,this
没有TimelinePanel
的成员。
因为似乎y_to_track
而x_to_time
没有使用this
,您可以将它们设为静态(在它们之前添加关键字static
)并将其称为以下:TimelinePanel.y_to_track
。
如果您需要访问绑定到TimelinePanel
的特定实例的方法,那么除了将此实例传递给Diamond
构造函数或重构TimelinePanel
之外,我没有看到任何其他解决方案。在Diamond
构造函数周围使用闭包。
在任何情况下,您似乎都在尝试复制类似Java的内部类的行为(例如,您可以使用ClassName.this
访问容器类实例或只访问容器类成员),没有这样的JS中的东西(至少有class
)。
TimelinePanel
的{{1}}成员,而您无法将其作为班级成员。最简单的似乎是将ctx_wrap
传递给TimelinePanel
构造函数:Diamond
和Diamond(frame, y, panel)
。如果将new this.Diamond(frame, y, this)
添加为Diamond
的成员,则会产生疑问。