2016-07-08 12 views
5

これはスコープの問題だと思いますが、これを修正する方法がわかりません。 addContentプリントしばらくオブジェクト、http://jsfiddle.net/9k9Pe/1498/javascript ES6クラスの「this」は未定義です

class FrameCreator{ 

    constructor(){ 
     this.createFrame(); 
    } 
    createFrame(){ 
     var iframe = document.createElement('iframe'); 
     this.iframe = iframe; 
     var frameLoaded=this.frameLoaded; 
     iframe.onload = function() { 
        frameLoaded(); 
     }; 
     document.body.appendChild(iframe); 
    } 
    frameLoaded(){ 
      console.log("frame loaded"); 
    } 
} 

class CustomFrameCreator extends FrameCreator{ 
    addContent(){ 
      console.log(this); // returns the object 
    } 
    frameLoaded(){ 
      console.log(this); // returns undefined 
    } 
} 

var frame=new CustomFrameCreator(); 
frame.addContent(); 

frameLoaded()プリント未定義: はここに私のコードです。

これを修正するには、フレームがロードされたときにこれを参照することができますか?

おかげ

+2

'iframe.onload =()=> this.frameLoaded()を試してみてください;' ' –

+1

VAR frameLoaded = this.frameLoaded;'スタータのため、それをしません。または少なくともそれを拘束する。 –

+0

'iframe.onload'でどの' frameLoaded'メソッドを実行したいのか、そして 'this'値を使うのかは不明です。 – Oriol

答えて

9

の別の代替のためのハンドラをバインドする必要がfiddle

+0

これは、関数を呼び出す関数を作成します。私はバインドほど効率的ではないと思う。確かに。 – frodeborli

+0

@frodeborli 'bind()'は関数を内部的にラップしますが、とにかくこれはpolyfillを実装する方法です。効率の悪い部分は、実際にスコープされた 'this'への参照です。関数のスコープでJavaScriptの最適化の可能性があるため、部分的に正しいですが、間違った理由があります。 –

4

使用bind機能は、コンテキスト

this.frameLoaded.bind(this); 

あなたはonload

iframe.onload = function() { 
    this.frameLoaded(); 
}.bind(this); 
0

を参照してください。バインドします

iframe.onload =() => { 
    this.frameLoaded(); 
}; 

class FrameCreator { 
 
    constructor() { 
 
    this.createFrame(); 
 
    } 
 
    
 
    createFrame() { 
 
    var iframe = document.createElement('iframe'); 
 
    this.iframe = iframe; 
 
    
 
    iframe.onload =() => { 
 
     this.frameLoaded(); 
 
    }; 
 

 
    document.body.appendChild(iframe); 
 
    } 
 
    
 
    frameLoaded() { 
 
    console.log("frame loaded"); 
 
    } 
 
} 
 

 
class CustomFrameCreator extends FrameCreator { 
 
    addContent() { 
 
    console.log(this); // returns the object 
 
    } 
 
    frameLoaded() { 
 
    console.log(this); // returns the object now 
 
    } 
 
} 
 

 
var frame = new CustomFrameCreator(); 
 
frame.addContent();

0

あなたのクラスを参照していませんonloadコールバック内に新しいスコープ、thisを作成しているので、代わりに参照:は、コンテキストを維持するためにES6アロー機能を使用することですコールバック関数自体。あなたは適切なthisArgのbindframeLoadedメソッドを必要とします。

class FrameCreator { 
 

 
    constructor() { 
 
    this.createFrame(); 
 
    } 
 
    createFrame() { 
 
    var iframe = document.createElement('iframe'); 
 
    this.iframe = iframe; 
 
    var frameLoaded = this.frameLoaded; 
 
    iframe.onload = frameLoaded.bind(this) 
 
    document.body.appendChild(iframe); 
 
    } 
 
    frameLoaded() { 
 
    console.log("frame loaded"); 
 
    } 
 
} 
 

 
class CustomFrameCreator extends FrameCreator { 
 
    addContent() { 
 
    console.log(this); // returns the object 
 
    } 
 
    frameLoaded() { 
 
    console.log(this); // returns undefined 
 
    } 
 
} 
 

 
var frame = new CustomFrameCreator(); 
 
frame.addContent();

関連する問題