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

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

    XMLWordPrintable

Details

    • 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)

    Description

      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

       

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

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

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes