Javascript 访问父变量的正确方法

Javascript Correct way to access parent variable

Qt 在 https://doc.qt.io/qt-5/qtquick-performance.html 中指定了以下代码。 accumulatedValue 变量被访问为“root.accumulatedValue”并且只是“accumulatedValue”。只是想知道在这种情况下访问父变量的正确方法是什么。

// 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;
    }
}

当从与它所属的对象相同的 scope 中访问 属性 时,不需要使用 id 限定该访问。从不同范围访问 属性 时,您应该使用 属性 所属对象的 id 对其进行限定。

使用qmllint举一些例子:

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;
    }
}

不合格的访问代价高昂,因为它们需要引擎搜索各种范围才能找到 属性。

另一个原因是可读性,在上面链接的范围文档中有解释:

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 [...]