2017-02-18 115 views
0

当我将一些开源ES5代码合并到我的ES6类中时,我得到了“Uncaught TypeError:this.time_to_x不是函数”。这里是班级(我已经删除了一些散装,但大部分基本的东西都在那里)。假设调用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

你是怎么调用'Diamond()'的? – 2017-02-18 02:20:48

+2

请说明你是怎么称呼'钻石'的。你很可能不会将“this”绑定到正确的对象。 – 4castle

+0

我不知道它是否与你的问题有关,但是你在'Diamond'里面定义'this.path'的方式是不正确的。这个函数里面的'this'不会是你想要的。解决这个问题最简单的方法是使用箭头函数编写'this.path =()=> {'。 – 2017-02-18 02:32:18

回答

2

因为你拥有它,它应该从封闭time_to_x,而不是从this的方式。在this没有这样的功能,所以this.time_to_x名称返回undefined这确实不是一个函数。

我建议水木清华这样的: 把var self = this;里面的类,但Diamond方法之外。 然后在Diamond内拨打self.time_to_x()

+0

好的,谢谢!那么在类的其他方法中调用方法的正确解决方案是什么? –

+0

我在同一个类中调用其他方法的方法与此相同。这个作品: 'create(){ this.myFunction(); } myFunction(){ var x = 1; var y = this.nextFunction(x); console.log(“test”+ y); } next函数(x){ return x * x; }' –

+0

^对不起,代码的迷你Markdown似乎没有工作 –

2

当您做new this.Diamond(frame, y)时,您正在创建this.Diamond类的实例。因此,在函数内部,this就是这个新实例,而不是它最初创建的TimelinePanel的实例。因此,this不具有TimelinePanel的成员。

因为好像y_to_trackx_to_time不使用的this,你可以让他们静(之前添加关键字static),并呼吁他们如下:TimelinePanel.y_to_track

如果您需要访问绑定到TimelinePanel特定实例的方法,那么我没有看到任何其他的解决办法不是通过这个实例的Diamond构造或重构TimelinePanel和使用封闭围绕Diamond构造。

在任何情况下,似乎你试图复制类似Java的内部类的行为(例如,你可以通过ClassName.this访问容器类实例或只访问容器类成员),JS中没有这样的事情(至少在class)。

编辑:我只是注意到,你正在访问TimelinePanelctx_wrap成员,你将无法作为类成员。最简单似乎通过TimelinePanelDiamond构造函数:Diamond(frame, y, panel)new this.Diamond(frame, y, this)。它将Diamond作为TimelinePanel的成员加入其中是有用的。

+0

@Quentin_Roy - 谢谢!使用静态和TimelinePanel.time_to_x的作品!解决了! –

+0

还不完全确定你对ctx_wrap的意思。到目前为止没有错误,它是有效的。但是如果我有更多的问题,请记住你说的话。 –

+0

在每个新的'Diamond'实例附加的'path'方法中,使用'this.ctx_wrap'。它不会被定义为'Diamond'实例。 –

相关问题