2017-02-18 114 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'實例。 –

相關問題