ES6类中的javascript'this'返回undefined

时间:2016-07-08 18:19:04

标签: javascript ecmascript-6 es6-class

我认为这是一个范围问题,但我不确定如何解决这个问题。 这是我的代码: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()打印未定义,而addContent打印对象。

如何解决这个问题,所以在加载框架时我可以在这里有一个参考?

由于

4 个答案:

答案 0 :(得分:11)

.bind()的另一种替代方法是使用ES6 Arrow函数来保留上下文:

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

答案 1 :(得分:6)

使用bind函数绑定上下文

this.frameLoaded.bind(this);

请参阅fiddle

答案 2 :(得分:1)

您需要绑定onload

的处理程序
iframe.onload = function () {
  this.frameLoaded();
}.bind(this);

答案 3 :(得分:0)

由于您正在创建新范围,this回调中的onload不会引用您的类,而是引用回调函数本身。您必须bind frameLoaded方法才能使用此方法。

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