Data types
Variables
A variable is a concept spanning almost all computer programming languages. A way to think about it is a coat check ticket at a venue. You have a coat to check in (ie. some data), you hand it over and you get back a ticket with a number on it. In the racks of coats and bags that are stored (ie. computer memory), it's this particular ticket that 'points to' or refers back to a particular coat.
A variable is like the ticket. Variables, like the tickets, are not the coats themselves, but rather just a reference to some data stored somewhere, somehow. Without the variable, the data is lost, just like losing a ticket means you can't retrieve a coat.
Over time, the same ticket number might be used to refer to different things. Maybe a venue is using plastic numbered tokens. When one person checks their coat in, they get #3129, but maybe the next night #3129 is used to refer to another person's handbag.
Larger venues might even have a coding system for their tickets so the clerk can quickly identify what rack an item can be found. Eg, blue tickets correspond to one rack, while red tickets correspond to another. In this case, the ticket helps to signify a set of items, and also a particular item within that set. Variables can also work like this.
Declaring variables
In the coat check you have to go through a little ritual of checking in your coat to get your ticket. You can't just dump your coat on the ground and hope it to be kept track of. Variables are the same. You need to formally declare them. When you do so, you give them a name
Variables can refer to different kinds of data and different kinds of data can be worked with in it own way. Luckily Javascript is not too fussy when it comes to data types, so it is hard to run into trouble.
Once you've declared a variable using let
, you can reassign it to whatever you want afterwards, even if that changes its type. Since it's already declared, don't use let
again when setting the value again.
let year = 1981; // Declare variable 'year' and assign an integer
year = 'Best ever'; // Assign value of 'year' to a string
If you don't expect that the variable will be reassigned, you can declare it with const
(short for constant) instead. Adding a self-imposed constraint like this can be helpful to catch mistakes in your code, since the browser will stop the variable being reassigned.
const year = 1981; // Decare as a constant
year = 'Best ever'; // TypeError: Assignment to constant variable
year = 2000; // TypeError: Assignment to constant variable
Booleans
Booleans can be thought of as simple true/false "switches". It is either true or it is false, there is no in-between.
let motorRunning = true; // Declares variable and sets to true
motorRunning = false; // Changes it to false
// ! means 'not', so here we're saying assign motorRunning to
// be not the value it currently is. The result is that
// it will flip from true to false or false to true.
motorRunning = !motorRunning;
Booleans - and the very idea of true/false - is the very foundation of computing, letting you make simple if-this-run-that-otherwise-do-this-other-thing kind of expressions:
// Print one of two statements depending on the value of 'motorRunning'
if (motorRunning) {
console.log('Cruising!');
} else {
console.log('Going nowhere');
}
Read more:
- Codecademy
- Boolean type (MDN)
Numbers
There are few different kinds of numbers, but for the most part, you just have to think of integers and floating point numbers ("floats").
Integers are simple numbers with no decimal points, eg: 0, 4, -120. Floats are numbers which can have decimal values, eg: 0.001, 99.9, -3.123. Percentages are represented as a float between 0 and 1, ie. 0.5 is 50%.
const age = 27; // Set an integer
const weight = 70.34; // Set a float
// Things to do with numbers
const doubleWeight = weight * 2; // Multiple
const halfAge = age / 2; // Divide
const oneYearOlder = age + 1; // Add
const younger = age - 10; // Subtract
Note here we are using constants since we're not changing the values, but rather computing new derivative values and assigning them to new variables. It's pretty common to mutate a value based on what it currently is:
let speed = 100;
speed = speed / 2; // Divide by two
// Shorter syntax for saying speed = speed * 0.5
speed *= 0.5; // Also divide by two
You can convert strings to numbers using parseInt
and parseFloat
in built functions. This can be useful if you need to convert user-entered text into a number, for example.
const height = parseFloat(el.value);
Not a Number (NaN)
Strange results can occur if you try mathematical operations with strings. Sometimes you see NaN
as the outcome. This stands for Not a Number. For example, trying parseFloat("hello!")
returns NaN
, because the string "hello!" cannot be converted to a float. NaN
is a bit tricky because any subsequent mathematical operation involving not-a-number will always result in not-a-number.
If you're seeing NaN, sometimes you need to trace it back to where it came from and do something more sensible at that point. You can use the in-built function isNaN
:
const height = parseFloat('pretty tall');
if (isNaN(height)) {
console.log("That's nonsense!");
return; // Exit function to avoid NaN spreading
}
height /= 2; // Half the height
Math functions
There are bunch of useful functions contained in Javascript's inbuilt Math
class:
// Returns the larger of two parameters
Math.max(2, 5); // 5
// Return the smaller of two parameters
Math.min(2, 5); // 2
// Return a random float between 0.0 and 1.0
Math.random();
// Return the lower integer of a float
Math.floor(10.2); // 10
// Return the upper integer of a float
Math.ceil(10.2); // 11
// Return the absolute value (ie, throw away the negative sign)
Math.abs(-10.2); // 10.2
Read more:
- Codecademy
- Math class (MDN)
Arrays
Arrays are like a set of boxes for data, and each box has an index (or "position") within an array. Programmers begin counting at 0, so the very first element in an array has an index of 0 (zero), the second an index of 1 and so on. Arrays are useful for storing a set of things. To create an array when you know what you want in it, use this square bracket notation:
const names = ['Thom', 'Jonny', 'Colin', 'Phil', 'Ed'];
const favouriteNumbers = [7, 127, 42];
To dynamically add to an array use unshift()
for adding to the front, or push()
to adding to the end:
const colours = ['blue', 'red', 'green'];
colours.unshift('purple'); // ["purple", "blue", "red", "green"]
colours.push('pink'); // ["purple", "blue", "red", "green", "pink"]
To remove from the front of an array use shift()
, or from the end of an array, pop()
:
const colours = ['purple', 'blue', 'red', 'green', 'pink'];
colours.shift(); // ["blue", "red", "green"]
colours.pop(); // ["blue", "red", "green"]
Why can we change arrays even though they are defined as a constant? This is perfectly legal because we're not changing what the variable points to. It's still the same array that we're manipulating. We cannot, however, assign a new array (or other value) to the constant.
const colours = ['purple', 'blue', 'red', 'green', 'pink'];
colours = ['mauve', 'moonshadow']; // Nope, can't reassign because it's a constant
To access something in an array you need to specify which item you want and you do this with its index and at
. Using negative indexes allow you to count from the last array element.
let secondName = names.at(1);
let secondLastName = names.at(-1);
You'll often see arrays being accessed using square bracket notation. Unlike at, you can't use negative indexes this way.
let secondName = names[1]; // same as names.at(1)
To get the length of the array, use the length
property:
console.log(names.length); // Prints: 5
To loop through an array with indexes (that is, the numerical position of each element):
for (const i = 0; i < names.length; i++) {
console.log('Name: ' + names.at(i));
}
If you don't care about the indexes, just the values, use a for .. of
loop:
for (const name of names) {
console.log('Name: ' + name);
}
You can do other things like grab sections of an array and remove sections as well, see Data Types Revisited
Read more:
Strings
A "string" is basically text. Very often this is human language, but can also be rather gibberish text which has no meaning for a human, like a colour hexcode. If you want to define a string, you have to start and end it with either a double or single quote mark: " or '. It doesn't matter which, as long as you use the same for a single string.
const singer = 'Thom Yorke';
const drums = 'Phil Selway';
If you want to include the same quote mark inside your string, you have to "escape" it by adding a backslash. Otherwise the interpreter won't know when your string is meant to end.
const dialogue = 'I can\'t wait to see "Titanic".';
Strings can be thought of as an array of characters. The first letter of a string therefore has a position 0, the second letter of a string position 1 and so on. Use at
to get the value at a certain position:
const dialogue = 'I can\'t wait to see "Titanic".';
console.log(dialogue.at(0)); // Prints: I
console.log(dialogue.at(5)); // Prints: t
console.log(dialogue.at(100)); // Prints: undefined - because there's no 100th character
Like arrays, you can also use a square bracket notation to access characters, but you can't use negative indexes:
console.log(dialogue.[0]); // Prints: I
Strings have a "length" property which is very handy when you don't know the contents of your string in advance. The last character of a string has a position of length-1 (because counting starts at 0).
const dialogue = 'I can\'t wait to see "Titanic".';
console.log(dialogue.length); // Prints: 30
console.log(dialogue.at(dialogue.length - 1)); // Prints: .
Giving negative numbers to at
allows you to get the _n_th index from the end of the string:
const letters = 'abcde'; // Six characters
console.log(letters.at(-2)); // Prints: d
console.log(letters.at(-5)); // Prints: a
console.log(letters.at(-6)); // Prints: undefined
If you want to find particular string within another string, use indexOf to find its starting position:
const dialogue = 'I can\'t wait to see "Titanic".';
const pos = dialogue.indexOf('Titanic');
console.log(pos); // Prints: 21
If you want to extract a bit of a string use substring(startIndex, endIndex)
const dialogue = 'I can\'t wait to see "Titanic".';
// Gets the text between position 5 and position 7: wa
let snippet = dialogue.substring(8, 10);
snipper = dialogue.substr(8, 10);
You can combine strings, or combine strings and other kinds of data using the +
sign:
const name = 'Colin';
const plays = 'guitar';
const songs = 5;
const line = name + ' plays ' + plays + ' on ' + songs + ' songs.';
console.log(line); // Prints: Colin plays guitar on 5 songs.
A more modern way of creating strings with data is using template literals. Here, we use the backtick `
operator to start and end the string instead of the usual single or double quote marks. Then, we're able to include references to variables by enclosing them in \${}
.
console.log(`${name} plays ${plays} on ${songs} songs.`);
The above example is far more readable and easier to maintain than concatenating strings.
You can do other useful things with strings, like convert to upper or lowercase, to replace bits of a string with something else, and convert a string into an array.
Read more:
- Codecademy
- String (MDN)
- Template literals (MDN)
Object
Objects have a few different senses in Javascript, but here I'll just describe a very elemental sense of an object which combines a few different named properties together:
const person = {
age: 27,
name: 'Barry'
};
Note the use of colons (:) to assign values to named properties, and the comma after each one. To read or change properties, use a dot notation:
console.log(person.name); // Prints: Barry
person.name = 'Sally';
console.log(person.name); // Prints: Sally
You can print a whole object out as well:
console.log(person); // Prints: { age: 27, name: "Barry" }