1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
4\page qtqml-documents-scope.html
5\title Scope and Naming Resolution
6\brief overview of scope and naming resolution
8QML property bindings, inline functions, and imported JavaScript files all
9run in a JavaScript scope. Scope controls which variables an expression can
10access, and which variable takes precedence when two or more names conflict.
12As JavaScript's built-in scope mechanism is very simple, QML enhances it to fit
13more naturally with the QML language extensions.
15\section1 JavaScript Scope
17QML's scope extensions do not interfere with JavaScript's natural scoping.
18JavaScript programmers can reuse their existing knowledge when programming
19functions, property bindings or imported JavaScript files in QML.
21In the following example, the \c {addConstant()} method will add 13 to the
22parameter passed just as the programmer would expect irrespective of the
23value of the QML object's \c a and \c b properties.
30 function addConstant(b) {
37That QML respects JavaScript's normal scoping rules even applies in bindings.
38This totally evil, abomination of a binding will assign 12 to the QML object's
49Every JavaScript expression, function or file in QML has its own unique
50variable object. Local variables declared in one will never conflict
51with local variables declared in another.
53\section1 Type Names and Imported JavaScript Files
55\l {QML Documents} include import statements that define the type names
56and JavaScript files visible to the document. In addition to their use in the
57QML declaration itself, type names are used by JavaScript code when accessing
58\l {Attached Properties and Attached Signal Handlers}{attached properties} and enumeration values.
60The effect of an import applies to every property binding, and JavaScript
61function in the QML document, even those in nested inline components. The
62following example shows a simple QML file that accesses some enumeration
63values and calls an imported JavaScript function.
67import "code.js" as Code
70 snapMode: ListView.SnapToItem
74 elide: Text.ElideMiddle
75 text: "A really, really long string that will require eliding."
76 color: Code.defaultColor()
82\section1 Binding Scope Object
84An object which has a \l{Property Binding}{property binding} is known as the
85binding's \e{scope object}. In the following example, the \l Item object is
86the binding's scope object.
90 anchors.left: parent.left
94Bindings have access to the scope object's properties without qualification.
95In the previous example, the binding accesses the \l Item's \c parent property
96directly, without needing any form of object prefix. QML introduces a more
97structured, object-oriented approach to JavaScript, and consequently does not
98require the use of the JavaScript \c this property.
100Care must be used when accessing \l {Attached Properties and Attached Signal Handlers}
101{attached properties} from bindings due
102to their interaction with the scope object. Conceptually attached properties
103exist on \e all objects, even if they only have an effect on a subset of those.
104Consequently unqualified attached property reads will always resolve to an
105attached property on the scope object, which is not always what the programmer
108For example, the \l PathView type attaches interpolated value properties to
109its delegates depending on their position in the path. As PathView only
110meaningfully attaches these properties to the root object in the delegate, any
111sub-object that accesses them must explicitly qualify the root object, as shown
116 delegate: Component {
120 scale: root.PathView.scale
127If the \l Image object omitted the \c root prefix, it would inadvertently access
128the unset \c {PathView.scale} attached property on itself.
130\section1 Component Scope
132Each QML component in a QML document defines a logical scope. Each document
133has at least one root component, but can also have other inline sub-components.
134The component scope is the union of the object ids within the component and the
135component's root object's properties.
139 property string title
143 text: "<b>" + title + "</b>"
145 anchors.top: parent.top
151 anchors.bottom: parent.bottom
156The example above shows a simple QML component that displays a rich text title
157string at the top, and a smaller copy of the same text at the bottom. The first
158\c Text type directly accesses the component's \c title property when
159forming the text to display. That the root type's properties are directly
160accessible makes it trivial to distribute data throughout the component.
162The second \c Text type uses an id to access the first's text directly. IDs
163are specified explicitly by the QML programmer so they always take precedence
164over other property names (except for those in the \l {JavaScript Scope}). For
165example, in the unlikely event that the binding's \l {Binding Scope Object}{scope
166object} had a \c titletype property in the previous example, the \c titletype
167id would still take precedence.
169\section1 Component Instance Hierarchy
171In QML, component instances connect their component scopes together to form a
172scope hierarchy. Component instances can directly access the component scopes of
175The easiest way to demonstrate this is with inline sub-components whose component
176scopes are implicitly scoped as children of the outer component.
180 property color defaultColor: "blue"
183 delegate: Component {
192The component instance hierarchy allows instances of the delegate component
193to access the \c defaultColor property of the \c Item type. Of course,
194had the delegate component had a property called \c defaultColor that would
195have taken precedence.
197The component instance scope hierarchy extends to out-of-line components, too.
198In the following example, the \c TitlePage.qml component creates two
199\c TitleText instances. Even though the \c TitleText type is in a separate
200file, it still has access to the \c title property when it is used from within
201the \c TitlePage. QML is a dynamically scoped language - depending on where it
202is used, the \c title property may resolve differently.
208 property string title
212 anchors.top: parent.top
217 anchors.bottom: parent.bottom
225 text: "<b>" + title + "</b>"
230Dynamic scoping is very powerful, but it must be used cautiously to prevent
231the behavior of QML code from becoming difficult to predict. In general it
232should only be used in cases where the two components are already tightly
233coupled in another way. When building reusable components, it is preferable
234to use property interfaces, like this:
241 property string title
246 anchors.top: parent.top
252 anchors.bottom: parent.bottom
259 property string title
262 text: "<b>" + title + "</b>"
267\section1 Overridden Properties
269QML permits property names defined in an object declaration to be overridden by properties
270declared within another object declaration that extends the first. For example:
276 property string title
277 property string detail
280 text: "<b>" + title + "</b><br>" + detail
283 function getTitle() { return title }
284 function setTitle(newTitle) { title = newTitle }
290 property string title
291 property string firstName
292 property string lastName
294 function fullName() { return title + " " + firstName + " " + lastName }
298Here, the name \c title is given to both the heading of the output text for Displayable,
299and also to the honorific title of the Person object.
301An overridden property is resolved according to the scope in which it is referenced.
302Inside the scope of the Person component, or from an external scope that refers
303to an instance of the Person component, \c title resolves to the property
304declared inside Person.qml. The \c fullName function will refer to the \c title
305property declared inside Person.
307Inside the Displayable component, however, \c title refers to the property
308declared in Displayable.qml. The getTitle() and setTitle() functions, and the
309binding for the \c text property of the Text object will all refer to the \c title
310property declared in the Displayable component.
312Despite sharing the same name, the two properties are entirely separate. An
313onChanged signal handler for one of the properties will not be triggered by
314a change to the other property with the same name. An alias to either property
315will refer to one or the other, but not both.
317\section1 JavaScript Global Object
319QML disallows type, id and property names that conflict with the properties
320on the global object to prevent any confusion. Programmers can be confident
321that \c Math.min(10, 9) will always work as expected!
323See \l {JavaScript Host Environment} for more information.