Javascript 'this' in ES6 classes return undefined

I think this is a problem with the area, but I'm not sure how to fix it. Here is my code: http://jsfiddle.net/9k9Pe/1498/

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() prints undefined, and addContent prints the object.

How to fix it, so I can have a link in this case when loading a frame?

thanks

+6
source share
4 answers

Another alternative to .bind() is to use the ES6 Arrow function to maintain context:

 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(); 
+10
source

Use bind to bind context

 this.frameLoaded.bind(this); 

See fiddle

+4
source

You need to bind a handler for onload

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

Since you are creating a new scope, this in the onload callback does not refer to your class, it refers to the callback function instead. You must bind your frameLoaded method for this frameLoaded to be correct.

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

All Articles