Web Platform Javascript

Data types revisited

typeof allows you to find out the type of a variable. This can be useful if you want to check if it's the right data type, or to take different action according to type:

if (typeof myVariable === 'string') {
    // do something if it's text
} else if (typeof myVariable === 'number') {
    // do something if it's a number
} else {
    // some other type, print it out
    console.log(typeof myVariable);
}

You'll only ever get back one of these results: number, string, boolean, object, function and undefined.

That undefined value can be used to check whether a variable exists or has a value defined:

function sayHello(name) {
    if (typeof name === 'undefined') {
        throw new Error('name is undefined');
    }
}
sayHello(); // triggers an exception

Arrays

To remove an item at particular index, use the splice function of an array. The basic syntax is: array.splice(startIndex, numberOfItemsToRemove). Splice modifies the source array and returns the items that were removed.

If numberOfItemsToRemove is not given, all the items from startIndex to the end are deleted - effectively chopping the array at startIndex.

Here are some examples:

const names = ['Thom', 'Jonny', 'Colin', 'Phil', 'Ed'];

// Remove first item (remember, arrays start at 0)
const itemRemoved = names.splice(0,1);
// Note: names.shift() would work the same

// Remove the last item
names.splice(names.length-1,1);

// Remove three items, starting at the fourth position
names.splice(3, 3);

// Remove all items after the third item
names.splice(3);

Splice can also add items at the position you removed items from, see the docs for more on this.

Read more about splice

There are a few other ways of modifying arrays:

  • Remove first item: shift
  • Remove last item: pop
  • Add items to beginning: unshift
  • Add item to end: push
  • Combine arrays: concat

Getting array contents

There are (at least) two formulations for traversing an array, depending on whether you care about the index of items. forEach provides a callback for each name/index pair, while the for .. of iterator gives you just the values.

const names = ['Thom', 'Jonny', 'Colin', 'Phil', 'Ed'];

// forEach
names.forEach(function(name, index) {
    console.log(`Name: ${name} index: ${index}`);
});

// for .. of
for (let name of names) {
    console.log(`Name: ${name}`);
}

If you want to get a chunk of an array, slice can help. The syntax for slice is array.slice(startIndex, endIndex). If endIndex is not specified, you'll get back everything from startIndex onwards.

const names = ['Thom', 'Jonny', 'Colin', 'Phil', 'Ed'];

// returns elements from 2nd onwards:
names.slice(2); // ["Colin", "Phil", "Ed"]

// returns elements 1 to 3, ie, second and third items
names.slice(1,3); // ["Jonny", "Colin"]

Finding

To find an item in an array you can traverse it and check each one, but if you don't need to do anything fancy, indexOf or includes does the job.

const names = ['Thom', 'Jonny', 'Colin', 'Phil', 'Ed'];

const index = names.indexOf('Thom');
console.log(names[index]); // 'Thom'

if (names.includes('Thom')) {
    // Yes, array contains 'Thom'
}

Sometimes though you want to run a bit of code for each item to see if it matches what you want. Find to the rescue:

// Return the index of the first name with a length greater than 4
const index = names.find(n => n.length > 4);

Perhaps you'd rather take your source array and filter it, creating a new array with items that match a certain condition:

const longNames = names.filter(name => name.length> 4);

Working with array items

map generates a new array from the basis of each element in a source array, allowing you to transform each one and leaving the source array unmodified.

This example from MDN:

const numbers = [1, 4, 9];
const doubles = numbers.map(function(num) {
  return num * 2;
});
// doubles is now [2, 8, 18]. numbers is still [1, 4, 9]

The "double arrow" syntax allows functions to be expressed succinctly:

var numbers = [1, 4, 9];
var doubles = numbers.map(num => num * 2);
// doubles is now [2, 8, 18]. numbers is still [1, 4, 9]

Meta

Arrays can be created from various kinds of collections using Array.from(source). You can check whether an object is an array or not with Array.isArray(o)

Sorting

Arrays can be easily sorted with sort, eg names.sort(). Often though you want to specify your own sorting logic, such as for complex objects.

myArray.sort(function(a, b) {
    if (a.age > b.age) return 1; // 1 means A is greater than B
    else if (a.age < b.age) return -1 // -1 means A is less than B
    return 0; // 0 means they are equal
});

To sort in the opposite direction, do a sort, and then call reverse() to reverse the order:

numbers.sort();
numbers.reverse();

Read more:

Strings

Covert case with toUpperCase() and toLowerCase().

Read more:

Objects

Usually we work with simple objects such as:

const person = {
    name: 'Jane',
    age: 76
}

The person variable has two properties, name and age.

If you want to work with one of the properties, use the "dot notation" to access them:

console.log(`Hello ${person.name}`);
const older = person.age + 10;

If you find yourself working a lot of an object's properties, you might want to reference them from variables. Destructuring simplifies this by declaring and assigning variables from an object in one step:

const { name, age } = person;
console.log(`${name} is ${age} years old.`);

You can delete a property using delete:

delete person.age; // { name: "Jane" }

Destructuring can also return an object with things removed.

// Lets say you have an object with this shape:
const person = { name: 'Jane', age: 76, eyeColour: 'green', favouriteFruit: 'mango', favouriteDrink: 'coffee'};

// Somewhere else in your code...
const {name,age, ...leftOver} = person;
// This would declare variables: name, age and leftOver.
// name = 'Jane',
// age = 76, and 
// leftOver = { eyeColour: 'green', favouriteFruit: 'mango', favouriteDrink: 'coffee'}

To get a list of an object's properties or keys, use Object.keys(). To get the values, you can use Object.values():

const person = { name: 'Jane', age: 76};
let keys = Object.keys(person)); // ['name', 'age']
let values = Object.values(person); // ['Jane', 76]

This might give you the hint that to count the number of keys of an object, you can try out something like this:

Object.keys(person).length;

You can also access the properties using the indexer or array notation:

console.log(person['name']); // Jane

Objects can be enumerated over using for .. in. The following code prints out each property and value for the variable person:

for (const key in person) {
    console.log(`key: ${key} value: ${person[key]}`);
}

If you want both the key and the value of the object, you can use entries():

const result = { apple: 0.9, orange: 0.5, banana: 1 }
for (const [key,value] of Object.entries(results)) {
    console.log(`Fruit: ${key} has probability of ${value}`);
}

If you have a bunch of variables which you want to bundle into an object together there is a trick for that:

const name = 'Johanne';
const speed = '40';
const racer = { name, speed };
// Object { name: 'Johanne', speed: 40 }

It's also possible to merge objects together, with duplicate keys overriding:

const defaultSettings = { size: 20, colour: 'blue' };
const userSettings = { size: 30, position: 4 };
const settings = Object.assign({}, defaultSettings, userSettings);
// Object { size: 30, colour: 'blue', position: 4}

Time & Dates

If you want to work with time, Date is your friend, and it incorporates both calendar date and time. It is not a type like some of the other examples here, but a built-in object.

See also: Timing
const rightNow = Date.now(); // Refers to the current moment

You can also create a date based on common representations:

const thatOtherTime = new Date(2010, 12, 19);

Once you have a Date, you can pull out parts of it:

console.log(thatOtherTime.getFullYear()); // 2010
console.log(thatOtherTime.getDate()); // 19

A common task is to get the difference between two Dates:

const startTime = Date.now();
// and at some other point:
const elapsed = Date.now() - startTime; // time in milliseconds

Read more: