Keen Learner
Keen Learner

Reputation: 195

Javascript Correct way to access parent variable

Qt specifies below code in https://doc.qt.io/qt-5/qtquick-performance.html. accumulatedValue variable is accessed as "root.accumulatedValue" and just "accumulatedValue". Just curious to understand What is the correct way to access parent variables in such situations.

// good.qml
import QtQuick 2.3

Item {
    id: root
    width: 200
    height: 200
    property int accumulatedValue: 0

    Text {
        anchors.fill: parent
        text: root.accumulatedValue.toString()
        onTextChanged: console.log("text binding re-evaluated")
    }

    Component.onCompleted: {
        var someData = [ 1, 2, 3, 4, 5, 20 ];
        var temp = accumulatedValue;
        for (var i = 0; i < someData.length; ++i) {
            temp = temp + someData[i];
        }
        accumulatedValue = temp;
    }
}

Upvotes: 2

Views: 456

Answers (1)

Mitch
Mitch

Reputation: 24416

When accessing a property from within the same scope as the object it belongs to, qualifying that access with an id is not necessary. When accessing that property from a different scope, you should qualify it with the id of the object that the property belongs to.

Using qmllint to give some examples:

import QtQuick 2.3

Item {
    id: root
    width: 200
    height: 200
    property int accumulatedValue: 0

    Text {
        /*
            Warning: unqualified access at /tmp/good.qml:20:21

                    objectName: accumulatedValue
                                ^^^^^^^^^^^^^^^^
            Note: accumulatedValue is a member of the root element
                  You can qualify the access with its id to avoid this warning:

                    objectName: root.accumulatedValue
        */
        objectName: accumulatedValue
        anchors.fill: parent
        // Fine; qualified with id.
        text: root.accumulatedValue

        Component.onCompleted: {
            /*
                Warning: unqualified access at /tmp/good.qml:36:19

                            print(accumulatedValue)
                                  ^^^^^^^^^^^^^^^^
                Note: accumulatedValue is a member of the root element
                      You can qualify the access with its id to avoid this warning:

                            print(root.accumulatedValue)
            */
            print(accumulatedValue)
        }
    }

    Component.onCompleted: {
        var someData = [ 1, 2, 3, 4, 5, 20 ];
        // Fine; in same scope.
        var temp = accumulatedValue;
        for (var i = 0; i < someData.length; ++i) {
            temp = temp + someData[i];
        }
        accumulatedValue = temp;
    }
}

Unqualified accesses are expensive, as they require the engine to search through various scopes in order to find the property.

Another reason is readability, explained in the scope documentation linked to above:

Dynamic scoping is very powerful, but it must be used cautiously to prevent the behavior of QML code from becoming difficult to predict. In general it should only be used in cases where the two components are already tightly coupled in another way. When building reusable components, it is preferable to use property interfaces [...]

Upvotes: 4

Related Questions