2016-07-08 14 views
5

Myślę, że jest to problem z zasięgiem, ale nie jestem pewien, jak to naprawić. Oto mój kod: http://jsfiddle.net/9k9Pe/1498/javascript 'this' w klasach ES6 zwraca undefined

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() drukuje niezdefiniowany, podczas addContent wydruków przedmiot.

Jak to naprawić, więc mogę mieć odwołanie w tej sytuacji po załadowaniu ramki?

Dzięki

+2

Spróbuj 'iframe.onload =() => this.frameLoaded();' ' –

+1

var frameLoaded = this.frameLoaded;' nie rób tego, na początek. lub przynajmniej go związać. –

+0

Nie jest jasne, która metoda 'frameLoaded' ma być uruchomiona w' iframe.onload' i z jaką wartością 'this'. – Oriol

Odpowiedz

9

Innym alternatywnym do .bind() jest użycie ES6 Strzałka funkcję zachowania kontekstu:

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

Spowoduje to utworzenie funkcji, która wywołuje funkcję. Podejrzewam, że nie jest tak skuteczny jak bind. Nie jestem tego pewien. – frodeborli

+0

@frodeborli 'bind()' zawija wewnętrznie funkcję, tak, w jaki sposób można zaimplementować polyfill. Część, która czyni ją mniej wydajną, jest w rzeczywistości odniesieniem do "tego", co zabija niektóre możliwości optymalizacji JavaScriptu w zakresie funkcji, więc częściowo jest to poprawne, ale z niewłaściwego powodu. –

4

Zastosowanie bind funkcja związać kontekst

this.frameLoaded.bind(this); 

Zobacz fiddle

0

Trzeba powiązać obsługi dla onload

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

Skoro tworzenia nowego zakresu, this obrębie onload zwrotnego nie odwołać swoją klasę, to zamiast referencji sama funkcja oddzwaniania. Musisz bind swój sposób frameLoaded do właściwego thisArg.

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();

Powiązane problemy