Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-98039

QML javascript: "this" in class ctor becomes undefined during if(){...} in arrow functions

XMLWordPrintable

    • Linux/X11
    • eeec9f03e9 (qt/qtdeclarative/dev) 53d42c9541 (qt/qtdeclarative/6.2) 63f71197ca (qt/qtdeclarative/6.3) 53d42c9541 (qt/tqtc-qtdeclarative/6.2) 63f71197ca (qt/tqtc-qtdeclarative/6.3) eeec9f03e9 (qt/tqtc-qtdeclarative/dev) 53d42c9541 (qt/qtdeclarative/6.2.4)

      In QML javascript, when executing a pure-javascript class constructor, "this" becomes momentarily undefined in either branch of a conditional

      if (cond) { ... }
      

      but is valid before and after the "if".

      This problem (seemingly) occurs only if the code is in the body of an anonymous arrow function. JS arrow functions do not provide "this" or do anything with it, so the symbol "this" should refer to the "this" in the closure scope, i.e. the class constructor;

      And it does, except within an 'if' statement!

      STEPS TO REPRODUCE: 
        Put the code shown below in a file and run 'qml' on it

      RESULTS:

       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

       

      // test.qml   (run 'qml' on this file)
      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();
        }
      }
      

      The problem goes away if .bind(this) is used, or if the constructor copies "this" to a temporary variable and the closure refers to that temp instead of the symbol "this".

      Previously on stackoverflow at https://stackoverflow.com/questions/69846086/qml-javascript-this-becomes-undefined-in-class-constructor-under-if-if/69858353#69858353

       

        For Gerrit Dashboard: QTBUG-98039
        # Subject Branch Project Status CR V

            ulherman Ulf Hermann
            jimav Jim Avera
            Vladimir Minenko Vladimir Minenko
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes