首页 > 解决方案 > QML javascript:如果在箭头函数中,“this”在 if(){...} 下的类构造函数中变得未定义

问题描述

在 QML javascript 中,当执行纯 javascript 类构造函数时,“this”在下面的代码中暂时未定义,if (cond) { ... }但在其他方面应该是有效的。

仅当代码位于匿名箭头函数的主体中时,才会出现此问题(似乎)。JS 箭头函数不提供“this”或对它做任何事情,所以符号this应该引用它在封闭范围内的定义,即类构造函数;它是,除了条件if (c) {...}

这有什么可以解释的?

import QtQuick 2.14
Item {
  Component.onCompleted: {
    class Bugtest {
      constructor() {
        this.foo = 123;
        ((arg) => {
          print("BEFORE if: this="+this+", foo="+this.foo);
          if (true) {
            print("DURING if: this="+this); //undefined here only!!
          }
          print("AFTER  if: this="+this+", foo="+this.foo);
        })(42);
        print("At constructor exit: this="+this+", foo="+this.foo);
      }
    };

    var xyz = new Bugtest();
  }
}

使用qml(或qmlscene )v6.2.1 或 v5.15.2运行上述内容会产生:

qml: BEFORE if: this=[object Object], foo=123
qml: DURING if: this=undefined
qml: AFTER  if: this=[object Object], foo=123
qml: At constructor exit: this=[object Object], foo=123

标签: javascriptqtqml

解决方案


这看起来确实像一个 QML 错误,其中“this”绑定的范围被破坏了。虽然我无法解释为什么会这样,但我找到了一种解决方法,您.bind(this)在输入函数之前明确表示,这会导致if条件的内容正确评估:

import QtQuick 2.15

Item {
  Component.onCompleted: {
    class Bugtest {
      constructor() {
        this.foo = 123;
        ((arg) => {
          console.log("BEFORE if: this="+this+", foo="+this.foo);
          if (true) {
            console.log("DURING if: this="+this+", foo="+this.foo); // now works in QML and JSFiddle
          }
          console.log("AFTER  if: this="+this+", foo="+this.foo);
        }).bind(this)(42); // added explicit 'this' bind here
        console.log("At constructor exit: this="+this+", foo="+this.foo);
      }
    };

    var xyz = new Bugtest();
  }
}

推荐阅读