Note this doesn't mean x
is always the same value - it just means it never changes after it is initialised. This can be a useful thing to know when reading over more complicated functions.
The JavaScript examples in Construct's Start Page are written to prefer const
, and the script editor in Construct will suggest changing variable declarations from let
to const
if they are never reassigned.
do-while
The do...while statement is a fairly uncommonly used variant on the standard while
loop that always runs its statements at least once. Sometimes it's a useful way to write a loop, and is worth knowing about.
for-in
This guide covered 'for-of' loops, but there's another kind using the in
keyword, that is mostly used in older code. It can be used to iterate the properties of an object. See for...in on MDN Web Docs for more details. However in modern code, the 'for-of' form is preferable, with Object.keys(), Object.values() or Object.entries() if you want to iterate object properties, values or both.
Legacy features
JavaScript has various old features that basically shouldn't be used any more, but you may come across them if you work with existing pieces of older code. These include:
- var for declaring variables, which has some unusual and fairly complicated quirks, which is why
let
is now preferred.
- Prior to the introduction of classes, writing object-oriented code in JavaScript typically involved modifying the prototype of functions. This can also still come in useful with classes in some more uncommon or advanced cases. You can learn more about this in Inheritance and the prototype chain.
- Older JavaScript code sometimes also runs in "sloppy mode", i.e. non-strict mode. In Construct all code always runs in strict mode, so the way "sloppy mode" works is not relevant to code written in Construct. But once again if you need to work with older code and so need to know how it works, the differences are noted in the MDN guide on strict mode.
- Construct always uses modules. Non-module scripts, also known as "classic" scripts, work slightly differently. Again this does not affect Construct as it always uses module scripts, but classic scripts have some small differences, notably that top-level variables are global rather than scoped to the file, and the inability to use
import
and export
statements (but you can use dynamic imports).
Quirks
Like most programming languages, JavaScript has some quirks - unusual things that work strangely or in unexpected ways. These are best avoided. They are generally just obscurities, accidents or leftovers from poor design decisions years ago that are now too difficult to change. Don't write code that relies on them. However sometimes you have to be aware of them, if only to make sure you steer clear.
Type conversions
You can find lots of weird results when converting types. For example:
// Convert empty array to number
Number([]) // 0
// Convert empty object to number
Number({}) // NaN
// Many operators automatically convert
// to numbers, producing weird results like:
1 / [] // Infinity (1 / 0)
1 + "1" // "11" (string)
true + true // 2 (1 + 1)
// Operators can also automatically convert
// to strings, with weird results like:
[1] + 1 // "11" (string)
[1, 2] + [3, 4] // "1,23,4" ("1,2" + "3,4")
Avoid writing any code that uses this! Make sure any type conversions are explicit and therefore intentional.
Non-strict equality
The non-strict equality operator ==
is allowed to convert types. This can produce odd results, which is a good reason to prefer strict equality ===
instead. Some examples of unexpected type conversions are shown below.
0 == "0" // true
0 == false // true
0 == [] // true
0 == [0] // true
"1" == [1] // true
"" == false // true
null == undefined // true
In every case above, using strict equals ===
returns false
instead of true
, as you'd probably want as in every case the types are different. So avoid using non-strict equality and don't rely on its type conversions as they can do unexpected things.
Array indices
If you access an array at a fractional index, it will return undefined
.
["😀", "👾"][0] // "😀"
["😀", "👾"][0.5] // undefined
The reason for this is a very strange part of JavaScript where technically the array elements are string properties that are a string of a number. Accessing arr[0.5]
actually accesses a property named "0.5", i.e. arr["0.5"]
, which does not exist in the array; accessing a non-existent property returns undefined
.
Many other programming languages avoid this by using a number for array indices that is automatically rounded. However since this does not happen in JavaScript, we have to make sure array indices are always whole numbers. Using Math.floor()
on the array index is a good way to do that. For example to access a random element from an array, use arr[Math.floor(Math.random() * arr.length)]
, since Math.random()
returns a fractional number, so it must be rounded down to a whole number.
More quirks
You'll probably come across other quirks or surprising things about JavaScript as you work more with it. Remember to try to avoid surprising parts of JavaScript - it's best to write clear code, and using obscure or accidental features of JavaScript makes your code harder to understand.