2017-10-24 10 views
1

例のコードでは、myOtherFuncは継承されたキャンバス変数を出力しますが、キャンバスをクリックしてmyFuncを呼び出すとthis.canvasは未定義として出力されます。どうしてこれなの?クラスのイベントハンドラがそのクラスの変数を継承しない理由

HTML:

<!DOCTYPE HTML> 
<html> 
<body> 
    <canvas id="drawCanvas" style="border:1px solid #000000;"></canvas> 
    <script> 
    class myClass { 
     constructor() { 
     this.canvas = document.getElementById('drawCanvas'); 
     this.ctx = this.canvas.getContext('2d'); 

     this.canvas.addEventListener('click', this.myFunc); 

     this.myOtherFunc(); 
     } 

     myFunc(event) { 
     console.log(this.canvas); 
     } 

     myOtherFunc() { 
     console.log(this.canvas); 
     } 
    } 

    let c = new myClass; 
    </script> 
</body> 
</html> 

答えて

2

thisは、canvas要素にアタッチされたclickイベントハンドラ内の要素自体であり、<canvas>要素です。 this<canvas>も本当に便利ありconsole

myFunc(event) { 
    console.log(this); 
} 
1

イベントハンドラのスコープは、キャンバスではなく、クラスであるためです。 this MDN referenceを参照して、bindの詳細については

this.canvas.addEventListener('click', this.myFunc.bind(this)); 

:あなたは、イベントハンドラにバインドthisする必要があります。

3

で記録されてundefinedその結果、質問のコードで要素で.canvasプロパティが設定されていない:

this.canvas.addEventListener('click', this); 

は、オブジェクトを渡す場合関数の代わりに、そのオブジェクトのhandleEventが呼び出され、これがオブジェクトになります。 handleEventの内部では、event.typeをチェックしてイベントの種類を調べることができます。例:

class Foo { 
    constructor(element) { 
     this.element = element; 
     element.addEventListener("mousedown", this); 
     element.addEventListener("mousemove", this); 
     element.addEventListener("mouseup", this); 
    } 
    handleEvent(event) { 
     // all events come here, so lets redistribute them: 
     this[event.type](event); 
    } 
    mousemove(event) { 
    } 
    mousedown(event) { 
    } 
    mouseup(event) { 
    } 
} 
関連する問題