Bent and hammered nail with an emoji face illustration. Done by Andre Coetzer
Section 3

JavaScript fundamentals (Part 2)

Lecture 32

Activating strict mode

                  
                    // Strict mode
                    'use strict';
                  
                

Activating strict mode allows writing more secure code, it will become a lot harder to make errors while writing the code. Activating strict mode should always be the first line, if anything is before that apart from comments, strict mode will not work.

Strict mode displays in your console possible errors such as variables that haven't been assigned, as well as possible use of reserved keywords within JavaScript. Always use strict mode.

Lecture 33

Functions

A function is a piece of code we can reuse over and over again.  In this sense, functions helps us keep our code DRY, which is an acronym for, Don't Repeat Yourself. Functions act much like a variable, storing lines of code inside. 

                  
                    // Function
                    function logger() {
                      console.log("Hello, my name is Andre");
                    }
                    
                    logger();
                    logger();
                    logger();
                    
                    const test = logger();
                    console.log(typeof test)
                  
                

The area inside the function where the code is written is known as the function body. To invoke or use the function, you simple call, run or invoke the function name and do not forget the parenthesis. 

It's worth noting, the above function will not return a value, even you had to capture it, the variable would be undefined.

                  
                    // Function with parameters and return
                    function juicer(nApples, nOranges) {
                      const juice = `Your juice is ${nApples} apples and ${nOranges} Oranges!`;
                      return juice;
                    }
                    const myJuice = juicer(3, 4);
                    console.log(myJuice);
                  
                

A function can take information and return information, this is done through the function's parameters, which allows for input. Parameters are placed within the parenthesis of the function. In this case, the parameters are nApples and nOranges, which take a value known as an argument. 

So, when declaring a function, the parameters are called parameters, while when invoking the function and adding a value to where the parameters were, is called an argument.

The return keyword returns a value, unlike logging this directly to the console, we need to capture it with a variable. If we just had to call the function, we still would not see the value, unless captured. Once the return keyword has taken place, the code will not run any further.

Lecture 33 — Assignment

Practice Assignment

  1. Write a function called 'describeCountry' which takes three parameters: 'country', 'population' and 'capitalCity'. Based on this input, the function returns a string with this format: 'Finland has 6 million people and its capital city is Helsinki'

  2. Call this function 3 times, with input data for 3 different countries. Store the returned values in 3 different variables, and log them to the console

                  
                    function describeCountry (country, population, capitalCity) {
                      const myCountry = `${country} has ${population} million people and it's capital is ${capitalCity}`;
                      return myCountry;
                    }
                    
                    const bulgaria = describeCountry('Bulgaria', 7.4, 'Sofia');
                    const southAfrica = describeCountry('South Africa', 60, 'Pretoria, Bloemfontein and Cape Town');
                    const columbia = describeCountry('Columbia', 50, 'Bogota');
                    
                    console.log(bulgaria);
                    console.log(southAfrica);
                    console.log(columbia);
                  
                
Lecture 34

Functions declarations vs. expressions

                  
                    // Declaring a function

                    const age1 = calcAge1(1989); // invoking function before declaration

                    function calcAge1 (birthYear) {
                      console.log('Declaring a function')
                      return 2023 - birthYear;
                    }

                    console.log(age1);

                    // Function expression

                    const calcAge2 = function (birthYear) {
                      console.log('Function expression')
                      return 2023 - birthYear;
                    }

                    const age2 = calcAge2(1989);

                    console.log(age2);
                  
                

When we declare a function, we initialize the function with the function keyword and then provide it a name. Whereas, when we do function expressions, we save the function to a variable. 

The function's expression's name is the variable name, this means the function defined inside the variable is known as an anonymous function because it has no name. This also points out that a function is not a type but an expression and, as we know, an expression returns a value. When invoking a function expression, we still need to assign it to a variable, much the same way as when we declare a function.

If everything works similarly, just written differently, what are the differences?

When declaring a function, you can call the function even before it has been declared. Meaning, your function does not have to be at the top of the page. A Function expression, however, does not allow this. You first need the expression before you can invoke the function, forcing you to write your function at the top of the page. 

This brings us to a question of which to use?

It comes down to personal preference, if you like declaring functions, then use that, if you prefer function expressions and writing your functions at the top of the page, then use that.

Function expressions seem more organized, keeping both values and functions inside variables and first declaring a function before invoking it, forcing a written structure.

Lecture 34 — Assignment

Practice Assignment

  1. The world population is 7900 million people. Create a function declaration called 'percentageOfWorld1' which receives a 'population' value, and returns the percentage of the world population that the given population represents. For example, China has 1441 million people, so it's about 18.2% of the world population

  2. To calculate the percentage, divide the given 'population' value by 7900 and then multiply by 100

  3. Call 'percentageOfWorld1' for 3 populations of countries of your choice, store the results into variables, and log them to the console

  4. Create a function expression which does the exact same thing, called 'percentageOfWorld2', and also call it with 3 country populations (can be the same populations)

                  
                    // Declaring functions
                    function percentageOfWorld1(population) {
                      return (population / 7900) * 100;
                    }
                    
                    const jamaicaPopulation = percentageOfWorld1(3);
                    const bulgariaPopulation = percentageOfWorld1(7.4);
                    const southAfricaPopulation = percentageOfWorld1(60);
                    
                    console.log(
                      `Jamaica's population is ${jamaicaPopulation.toFixed(2)}% of the world's population`
                    );
                    console.log(
                      `Bulgaria's population is ${bulgariaPopulation.toFixed(2)}% of the world's population`
                    );
                    console.log(
                      `South Africa's population is ${southAfricaPopulation.toFixed(2)}% of the world's population`
                    );
                    
                    // Function expressions
                    const percentageOfWorld2 = function () {
                      return (population / 7900) * 100;
                    };
                    
                    const americaPopulation = percentageOfWorld1(332);
                    const canadaPopulation = percentageOfWorld1(37);
                    const mexicoPopulation = percentageOfWorld1(129);
                    
                    console.log(
                      `America's population is ${americaPopulation.toFixed(2)}% of the world's population`
                    );
                    console.log(
                      `Canada's population is ${canadaPopulation.toFixed(2)}% of the world's population`
                    );
                    console.log(
                      `Mexico's population is ${mexicoPopulation.toFixed(2)}% of the world's population`
                    );
                  
                
Lecture 35

Arrow functions

                  
                    // Arrow function
                    const calcAge3 = birthYear => 2023 - birthYear;
                    const age3 = calcAge3(1989);
                  
                

Arrow functions is a shorter syntax for function expressions they do not support the 'this' keyword, as we will see later in the course.

Arrow functions, that have but one parameter and a single line of code, are known as one-liner functions. We do not need to place parenthesis around the parameter, nor use the 'return' keyword, as it is implicit.

                  
                    const yearsBeforeRetirement = (birthYear, firstName) => {
                    const age = 2023 - birthYear;
                    const retirement = 65 - age;

                    return `${firstName}'s retirement is in ${retirement} years`;
                    };

                    console.log(yearsBeforeRetirement(1989, 'Andre'));
                  
                

In the above example, the arrow function has more than a single parameter, so we need to use parenthesis. We also require code block brackets as there is more than a single line of code. The 'return' keyword is also required, as it is no longer a one-liner function.

Again, we ask, which function to use?

The answer is still function expressions. As mentioned earlier that arrow functions are great as one-liner functions, but they don't support the 'this' keyword which is given to a function associated with objects (methods).

Lecture 35 — Assignment

Practice Assignment

  1. Recreate the last assignment, but this time create an arrow function called'percentageOfWorld3'

                  
                    const percentageOfWorld3 = (population) => (population / 7900) * 100;

                    const columbiaPopulation = percentageOfWorld1(50);
                    const swedenPopulation = percentageOfWorld1(10.4);
                    const japanPopulation = percentageOfWorld1(126.17);

                    console.log(`
                    Columbia's population is ${columbiaPopulation}% of the world's population,
                    Sweden's population is ${swedenPopulation}% of the world's population,
                    Japan's population is ${japanPopulation}% of the world's population.
                    `);
                  
                
Lecture 36

Functions calling other functions

In JavaScript, we can call other functions inside functions. We have been doing this to some degree using console.log( ... ).

                  
                    // cutting the fruit into pieces
                    const fruitPieces = function (fruit) {
                      return fruit * 6;
                    }

                    // juicing the fruiting together using the pieces
                    const juicer = function (apples, oranges) {
                      const applePieces = fruitPieces(apples);
                      const orangePieces = fruitPieces(oranges);

                      return `Your juice was made with ${applePieces} apple pieces and ${orangePieces} orange pieces.`
                    }

                    console.log(juicer(3, 2));
                  
                

Above, we could have done the calculation within the juicer function. Though to illustrate how functions can work inside other functions, this is a prime example.

It also follows the principle, if this juice had many more arguments, then repeating this code would be better suited for a function. Always let your code be DRY.

Lecture 36 — Assignment

Practice Assignment

  1. Create a function called 'describePopulation'. Use the function type you like the most. This function takes in two arguments: 'country' and 'population', and returns a string like this: 'China has 1441 million people, which is about 18.2% of the world.'

  2. To calculate the percentage, 'describePopulation' call the 'percentageOfWorld1' you created earlier.

  3. Call 'describePopulation' with data for 3 countries of your choice.

                  
                    const describePopulation = function (country, population) {
                    return `${country} has ${population} million people, which is ${percentageOfWorld1(population)}% of the world`
                    }

                    console.log(describePopulation('Bahamas', 397))
                    console.log(describePopulation('India', 1350))
                    console.log(describePopulation('Brazil', 215))
                  
                
Lecture 37

Reviewing functions

                  
                    const calcAge = function (birthYear) {
                      return 2023 - birthYear;
                    }

                    const yearsBeforeRetirement = function (birthYear, firstName) {
                      const age = calcAge(birthYear);
                      const retirement = 65 - age;

                      if (retirement >= 1) {
                        return `${firstName} has ${retirement} years before retirement`;
                      } else {
                        return -1; // no value
                      };
                    };

                    console.log(yearsBeforeRetirement(1989, 'Andre'))
                    console.log(yearsBeforeRetirement(1945, 'John'))
                  
                

As we review functions, it's important to note that parameters are like local variables for the function. We can use the same parameter name in other function parameters without issues.

In programming, -1 is used to denote that there is no value or meaning. 

Once a return has executed, the function will stop. This is known as the function has returned.

                  
                    // Function declaration
                    function myFunc1 () {
                      function body
                    }

                    // Function expression
                    const myFunc2 = function () {
                      function body
                    }

                    // Arrow function
                    // One Liner
                    const myfunc3 = parameter => parameter / 2;

                    // Multiline
                    const myFunc4 = (parameter1, parameter2) => {
                      return ...
                    }
                  
                

There are 3 types of functions, function declarations, function expressions and arrow functions. Function declaration can be invoked even before the function is declared, this giving you the freedom to place functions wherever in your code.

A function expression cannot be invoked before it's declared, therefore having a more structure approached to coding. Arrow functions, being much the same as function expressions, just using shorter syntax, does not support the 'this keyword'.

Arrow functions are great for one-liner functions, they can have no parenthesis and have implicit returns, making your code shorter and cleaner.

Functions can receive data, transform data and return data. They can operate within other functions. When declaring a function a parameter is called a parameter, though when invoking the function and placing the value in the parameters, that is called the arguments.

Parameters are also like local variables to that specific function. The code within a function is referred to as the function body.

Lecture 38

Coding challenge - 1

Back to the two gymnastics teams, the Dolphins and the Koalas! There is a new gymnastics discipline, which works differently. Each team competes 3 times, and then the average of the 3 scores is calculated (so one average score per team). A team only wins if it has at least double the average score of the other team. Otherwise, no team wins!

Your Tasks:
  1. Create an arrow function 'calcAverage' to calculate the average of 3 scores.

  2. Use the function to calculate the average for both teams.

  3. Create a function 'checkWinner' that takes the average score of each team as parameters ('avgDolhins' and 'avgKoalas'), and then logs the winner to the console, together with the victory points, according to the rule above. Example: "Koalas win (30 vs. 13)".

  4. Use the 'checkWinner' function to determine the winner for both Data 1 and Data 2.

  5. Ignore draws this time.

Test Data:
  • Data 1: Dolphins score 44, 23 and 71. Koalas score 65, 54 and 49.

  • Data 2: Dolphins score 85, 54 and 41. Koalas score 23, 34 and 27.

Hints:
  • To calculate average of 3 values, add them all together and divide by 3.

  • To check if number A is at least double number B, check for A >= 2 * B. Apply this to the team's average scores 😉.

                  
                    const calcAverage = (a, b, c) => (a + b + c) / 3;

                    // Test data 1
                    let scoreDolphins = calcAverage(44, 23, 71);
                    let scoreKoalas = calcAverage(65, 54, 49);

                    const checkWinner = function (avgDolphins, avgKoalas) {
                      if (avgDolphins >= 2 * avgKoalas) {
                        return `Dolphin's win (${avgDolphins} vs. ${avgKoalas})`;
                      } else if (avgKoalas >= 2 * avgDolphins) { 
                        return `Koala's win (${avgKoalas} vs. ${avgDolphins})`;
                      } else {
                        return `No one won...`
                      };
                    };

                    console.log(checkWinner(scoreDolphins, scoreKoalas));

                    // Test data 2
                    scoreDolphins = calcAverage(85, 54, 41);
                    scoreKoalas = calcAverage(23, 34, 27);

                    console.log(checkWinner(scoreDolphins, scoreKoalas));
                  
                
Lecture 39

Introduction to arrays

                  
                    // Creating arrays

                    const friend1 = 'Scott';
                    const friend2 = 'Frank';
                    const friend3 = 'Jack';

                    // Array literal
                    const friends = ['Scott', 'Frank', 'Jack'];

                    // Creating an array using a function
                    const arr = new Array(1989, 1990, 1991, 1992);
                  
                

Arrays are what is known as data structures in JavaScript. JavaScript has but 2 data structures, arrays and objects, though arrays are objects as we will learn later on, they just a special kind of object as they have their own methods, as we learn about methods, is that functions associated with objects become methods.

There are many ways to create an array, as seen above. The first example is what is known as an array literal, and is the easiest syntax for creating arrays. While the bottom is using functions to create an array.

                  
                    // Retrieving an indexed array

                    console.log(friends[0]);
                    console.log(friends.length);
                    console.log(friends[friends.length -1]);
                  
                

The way we can retrieve a value from an array, is by using brackets with the index value starting at 0. The brackets within arrays [ ... ] can hold an expression, as we know, expressions return a value.

                  
                    // Mutating arrays elements

                    friends[2] = 'Sammy'; // This is allowed
                    friends = ['Bob', 'Maria', 'Justin'] // This is not allowed
                  
                

Array values, are mutable, though you cannot change the entire array. Even though the array was assigned to a const variable, it's it still mutable. In JavaScript, values that are not mutable with a const variable are primitive values, arrays are not a type but a data structure.

                  
                    const firstName = 'Andre';

                    const andre = [
                      firstName,
                      'Coetzer',
                      33,
                      'Developer',
                      friends,
                    ]

                    console.log(andre)
                    console.log(`${andre[0]}'s best friend is ${andre[andre.length -1][0]}`)
                  
                

An array can hold different types of values, it can even nest other arrays or data structures inside of it. To select values within nested arrays, we simply use multiple brackets.

Lecture 39 — Assignment

Practice Assignment

  1. Create an array containing 4 population values of 4 countries of your choice. You may use the values you have been using previously. Store this array into a variable called 'populations'.

  2. Log to the console whether the array has 4 elements or not (true or false).

  3. Create an array called 'percentages' containing the percentages of the world population for these 4 population values. Use the function 'percentageOfWorld1' that you created earlier to compute the 4 percentage values.

                  
                    const populations = [7, 60, 320, 50];

                    console.log(populations.length === 4);
                    console.log(populations);

                    function percentageOfWorld1 (population) {
                      const percentage = (population / 7900) * 100;

                      return percentage.toFixed(2);
                    };

                    const percentages = [
                      percentageOfWorld1(populations[0]),
                      percentageOfWorld1(populations[1]),
                      percentageOfWorld1(populations[2]),
                      percentageOfWorld1(populations[3])
                    ];
                  
                
Lecture 40

Basic array operations (Methods)

                  
                    // Let's make a burger
                    const burger = [
                      'Patty',
                    ]

                    console.log(burger);

                    // To add an element to the end of an array
                    burger.push('Bottom Bun')
                    console.log(burger);

                    // To add an element to the start of an array
                    burger.unshift('Top Bun')
                    console.log(burger);
                  
                

With arrays, we have what is known as array methods or array operations. The first is '.push( ... )'. This will allow us to push further elements to the end of the array. We then have '.unshift( ... )' which adds elements to the front of the array.

                  
                    // Oh no! Our burger's bun is stale, lets remove it

                    // To remove an element to the end of an array
                    burger.pop();
                    console.log(burger);

                    // To remove an element to the start of an array
                    burger.shift();
                    console.log(burger);
                  
                

We then have the reverse of putting in, and that is removing elements from arrays. '.pop( ... )' removes from the end of an array, also returns the removed element. '.shift( ... )' removes from the beginning.

                  
                    const findWaldo = [
                      'not Waldo',
                      'not Waldo',
                      'not Waldo',
                      'Waldo',
                      'not Waldo',
                      'not Waldo'
                    ];

                    // checking the index value of waldo
                    console.log(findWaldo.indexOf('Waldo'));

                    // checking if waldo is in the array
                    console.log(findWaldo.includes('Waldo'));
                  
                

The above methods are very useful, they help you find or understand if an element is within an array. '.index( ... )' return the index position of an element, while the more modern way of doing it, '.include( ... )' returns a boolean value. The '.include( ... )' also uses strict equality and is more useful in the real world.

Lecture 40 — Assignment

Practice Assignment

  1. Create an array containing all the neighbouring countries of a country of your choice. Choose a country which has at least 2 or 3 neighbours. Store the array into a variable called 'neighbours'.

  2. At some point, a new country called 'Utopia' is created in the neighbourhood of your selected country. So add it to the end of the 'neighbours' array.

  3. Unfortunately, after some time, the new country is dissolved. So remove it from the end of the array.

  4. If the 'neighbours' array does not include the country ‘Germany’, log to the console: 'Probably not a central European country :D'.

  5. Change the name of one of your neighbouring countries. To do that, find the index of the country in the 'neighbours' array, and then use that index to change the array at that index position. For example, you can search for 'Sweden' in the array, and then replace it with 'Republic of Sweden'.

                  
                    const neighbours = [
                      'Canada',
                      'Mexico'
                    ];
                    console.log(neighbours);

                    neighbours.push('Utopia');
                    console.log(neighbours);

                    neighbours.pop();
                    console.log(neighbours);

                    if (!neighbours.includes('Germany')) {
                      console.log('Probably not a European country.')
                    }

                    neighbours[neighbours.indexOf('Canada')] = 'Conodo';
                    console.log(neighbours);
                  
                
Lecture 41

Coding challenge - 2

Steven is still building his tip calculator, using the same rules as before: Tip 15% of the bill if the bill value is between 50 and 300, and if the value is different, the tip is 20%.

Your Tasks:
  1. Write a function 'calcTip' that takes any bill value as an input and returns the corresponding tip, calculated based on the rules above (you can check out the code from first tip calculator challenge if you need to). Use the function type you like the most. Test the function using a bill value of 100.

  2. And now let's use arrays! So create an array 'bills' containing the test data below.

  3. Create an array 'tips' containing the tip value for each bill, calculated from the function you created before.

  4. Bonus : Create an array 'total' containing the total values, so the bill + tip.

Test Data:
  • 125, 555 and 44

Hints:
  • Remember that an array needs a value in each position, and that value can actually be the returned value of a function! So you can just call a function as array values (so don't store the tip values in separate variables first, but right in the new array) 😉.

                  
                    const calcTip = function (bill) {
                      return bill >= 50 && bill <= 300 ? bill * 0.15 : bill * 0.20;
                    };

                    console.log(calcTip(100));

                    const bills = [125, 555, 44];

                    const tips = [
                      calcTip(bills[0]),
                      calcTip(bills[1]),
                      calcTip(bills[2])
                    ];

                    console.log(tips);

                    const total = [
                      bills[0] + tips[0],
                      bills[1] + tips[1],
                      bills[2] + tips[2]
                    ];

                    console.log(total);
                  
                
Lecture 42

Introduction to objects

                  
                    const firstName = 'Andre';
                    const friends = ['Scott', 'Frank', 'Jack'];

                    // The array version
                    const andreArr = [
                      firstName,
                      'Coetzer',
                      33,
                      'Developer',
                      friends,
                    ];

                    // The object version
                    const andreObj = {
                      firstName: firstName,
                      lastName: 'Coetzer',
                      age: 2023 - 1989,
                      job: 'Developer',
                      friends: friends
                    };

                    console.log(andreObj);
                    console.log(andreObj.firstName);
                  
                

When it comes to objects, they answer a problem we have with arrays, which is knowing where data is. When it comes to arrays, we intuitively have to know with what the first index corresponds with. Is it the first name, the last name or the age if the array was about a person, however with objects we have what is known as key value pairs.

We can essentially assign a key to a value, which means we don't have to worry about ordering our data structure, whereas with arrays we do. Each key is also known as a property.

There are multiple ways to make objects, much like the array, but the object literal is the easiest way. 

The big difference between objects and arrays are, an array is more for structured data, while objects are not. Structure is more important for arrays and not objects.

Lecture 42 — Assignment

Practice Assignment

  1. Create an object called 'myCountry' for a country of your choice, containing properties 'country', 'capital', 'language', 'population' and 'neighbours' (an array like we used in previous assignments).

                  
                    const myCountry = {
                      country: 'Republic of Bulgaria',
                      capital: 'Sofia',
                      language: 'Bulgarian',
                      population: 7.4,
                      neighbours: [
                        'Greece',
                        'Republic of Macedonia',
                        'Romania',
                        'Serbia',
                        'Turkey'
                      ]
                    };

                    console.log(myCountry.country);
                  
                
Lecture 43

Dot vs. bracket notation

                  
                    const firstName = 'Andre';
                    const friends = ['Scott', 'Frank', 'Jack'];
                                      
                    const andreObj = {
                      firstName: firstName,
                      lastName: 'Coetzer',
                      age: 2023 - 1989,
                      job: 'Developer',
                      friends: friends
                    };
                    
                    // Dot notation
                    console.log(andreObj.job);
                    
                    // Bracket notation
                    console.log(andreObj['job']);
                    
                    // Brackets allow for expressions
                    const nameKey = 'Name';
                    
                    console.log(andreObj['first' + nameKey]);
                    console.log(andreObj['last' + nameKey]);
                  
                

This is how we can retrieve data from objects. The difference between Dot and Bracket is that the bracket notation allows for expressions. We can prove this by looking at the operator precedence table, where they refer to the Dot notation as Member Access and the Bracket notation as the computed Member Access.

This is important when trying to understand which to use, and it's simple, when you need to compute something, use the bracket notation and when not use the dot notation.

                  
                    const interestedIn = prompt('What would you like to know about Andre?, You can choose from firstName, lastName, age, job, friends');

                    console.log(andreObj.interestedIn) // Will result in undefined
                    console.log(andreObj[interestedIn]) // Will compute the value

                    if (andreObj[interestedIn]) {
                      console.log(andreObj[interestedIn]);
                    } else {
                      console.log('Unknown property');
                    };
                  
                

If we had to take user input and place it as a property, it will not compute the value, whereas the brackets first evaluate the expression and then returns the value.

                  
                    andreObj.location = 'Bulgaria';
                    andreObj['website'] = 'https://acoetzer.github.io';

                    console.log(andreObj);
                  
                

We can also assign new properties to an object using both Dot and Bracket Notation.

Challenge

Write a dynamic sentence using an object. Example — Andre has 3 friends, and his best friend is Whoever.

                  
                    const firstName = 'Andre';
                    const friends = ['Scott', 'Frank', 'Jack'];

                    const andreObj = {
                      firstName: firstName,
                      lastName: 'Coetzer',
                      age: 2023 - 1989,
                      job: 'Developer',
                      friends: friends
                    };

                    console.log(`${andreObj.firstName} has ${andreObj.friends.length} friends and his best friend is ${andreObj.friends[0]}`);
                  
                
Lecture 43 — Assignment

Practice Assignment

  1. Using the object from the previous assignment, log a string like this to the console: 'Finland has 6 million finnish-speaking people, 3 neighbouring countries and a capital called Helsinki.'

  2. Increase the country's population by two million using dot notation, and then decrease it by two million using brackets notation.

                  
                    const myCountry = {
                      country: 'Republic of Bulgaria',
                      capital: 'Sofia',
                      language: 'Bulgarian',
                      population: 7.4,
                      neighbours: [
                        'Greece',
                        'Republic of Macedonia',
                        'Romania',
                        'Serbia',
                        'Turkey'
                      ]
                    };

                    console.log(`The ${myCountry.country} has ${myCountry.population} million ${myCountry.language}-speaking people, ${myCountry.neighbours.length} neighbouring countries and a capital called ${myCountry.capital}`);

                    console.log(myCountry.population)

                    myCountry.population += 2;
                    console.log(myCountry.population);

                    myCountry['population'] -= 2;
                    console.log(myCountry.population);
                  
                
Lecture 44

Object methods

                  
                    const firstName = 'Andre';
                    const friends = ['Scott', 'Frank', 'Jack'];

                    const andreObj = {
                      firstName: firstName,
                      lastName: 'Coetzer',
                      birthYear: 1989,
                      calcAge: function () {
                        this.age = 2023 - this.birthYear;
                        return this.age
                      },
                      job: 'Developer',
                      friends: friends
                    };

                    andreObj.calcAge(); // Need to run the method first
                    console.log(andreObj.age);
                  
                

Any function that is associated with an object is known as a method. Which is why they say, all methods are functions, but not all function are methods.

A method is also just a property that holds a function, which is why we don't declare it but use a function expression.

The 'this' keyword is a special variable for methods. The 'this' keyword points to the object it is in.

Challenge

Write a method called getSummary that returns a summary of Andre like so — Andre is a 33-year-old developer who has or hasn't cooked dinner today.

                  
                    const firstName = 'Andre';
                    const friends = ['Scott', 'Frank', 'Jack'];

                    const andreObj = {
                      firstName: firstName,
                      lastName: 'Coetzer',
                      birthYear: 1989,
                      calcAge: function () {
                        this.age = 2023 - this.birthYear;
                        return this.age
                      },
                      job: 'Developer',
                      friends: friends,
                      hasCooked: false,
                      getSummary: function () {
                        return `${this.firstName} is a ${this.age}-year-old ${this.job} who ${this.hasCooked ? 'has' : "has't"} cooked dinner today`;
                      }
                    };

                    andreObj.calcAge();
                    console.log(andreObj.getSummary());
                  
                
Lecture 44 — Assignment

Practice Assignment

  1. Add a method called 'describe' to the 'myCountry' object. This method will log a string to the console, similar to the string logged in the previous assignment, but this time using the 'this' keyword.

  2. Call the 'describe' method

  3. Add a method called 'checkIsland' to the 'myCountry' object. This method will set a new property on the object, called 'isIsland'. 'isIsland' will be true if there are no neighbouring countries, and false if there are. Use the ternary operator to set the property.

                  
                    const myCountry = {
                    country: 'Republic of Bulgaria',
                    capital: 'Sofia',
                    language: 'Bulgarian',
                    population: 7.4,
                    neighbours: [
                      'Greece',
                      'Republic of Macedonia',
                      'Romania',
                      'Serbia',
                      'Turkey'
                    ],
                    describe: function () {
                      return `The ${this.country} has ${this.population} million ${this.language}-speaking people, ${this.neighbours.length} neighbouring countries and a capital called ${this.capital}`;
                    },
                    checkIsland: function () {
                      this.isIsland = this.neighbours.length === 0 ? true : false;
                      return this.isIsland;
                    }
                  };

                  console.log(myCountry.describe())
                  console.log(myCountry.checkIsland())
                  
                
Lecture 45

Coding challenge - 3

Let's go back to Mark and John comparing their BMIs! This time, let's use objects to implement the calculations! Remember: BMI = mass / height ** 2 = mass / (height * height) (mass in kg and height in meter).

Your Tasks:
  1. For each of them, create an object with properties for their full name, mass, and height (Mark Miller and John Smith).

  2. Create a 'calcBMI' method on each object to calculate the BMI (the same method on both objects). Store the BMI value to a property, and also return it from the method.

  3. Log to the console who has the higher BMI, together with the full name and the respective BMI. Example: "John's BMI (28.3) is higher than Mark's (23.9)!".

Test Data:
  • Marks weights 78 kg and is 1.69 m tall. John weights 92 kg and is 1.95 m tall.

                  
                    const mark = {
                      fullName: 'Mark Miller',
                      mass: 78,
                      height: 1.69, 
                      calcBMI: function () {
                        this.bmi = this.mass / this.height ** 2;
                        return this.bmi
                      }
                    };

                    const john = {
                      fullName: 'John Smith',
                      mass: 92,
                      height: 1.95, 
                      calcBMI: function () {
                        this.bmi = this.mass / this.height ** 2;
                        return this.bmi
                      }
                    };

                    mark.calcBMI()
                    john.calcBMI()

                    console.log(mark.bmi, john.bmi)

                    const bmiCompare = function (x, y) {
                      if (x.bmi > y.bmi) {
                        return `${x.fullName}'s BMI(${x.bmi}) is higher than ${y.fullName}'s BMI(${y.bmi})`
                      } else {
                        return `${y.fullName}'s BMI(${y.bmi}) is higher than ${x.fullName}'s BMI(${x.bmi})`
                      }
                    }

                    console.log(bmiCompare(mark, john));
                  
                
Lecture 46

Iteration — The for loop

Looking back at the 'if statement'  we now know that that is a control structure, loops are much the same. Loops help us repeat repetitive tasks, for this we use what is known as a 'for loop'.

                  
                    // Incremental
                    for (let i = 0; i <= 10; i++) {
                      console.log(`Iteration (${i})`);
                    };

                    // Decremental
                    for (let i = 10; i >= 0; i--) {
                      console.log(`Iteration (${i})`);
                    }
                  
                

The first example of a loop is a 'for loop', there is another known as the 'for ... in' loop, which will see later in the course. The 'for loop', consist of 3 parts, the declaration or variable assignment, the condition and the incremental or decremental.

Lecture 46 — Assignment

Practice Assignment

  1. There are elections in your country! In a small town, there are only 50 voters. Use a for loop to simulate the 50 people voting, by logging a string like this to the console (for numbers 1 to 50): 'Voter number 1 is currently voting'.

                  
                    for (let i = 1; i <= 50; i++) {
                      console.log(`Voter number ${i} is currently voting`);
                    };
                  
                
Lecture 47

Looping arrays, breaking and continuing

                  
                    const simpleArray = [
                      'Text-1',
                      'Text-2',
                      'Text-3',
                      23,
                      true,
                      'Text-4',
                      1991,
                      false,
                      'Text-5'
                    ];

                    const simpleArray2 = [];

                    for (let i = 0; i <= simpleArray.length; i++) {
                      console.log(`${simpleArray[i]} is a ${typeof simpleArray[i]}`);
                      simpleArray2.push(typeof simpleArray[i]);
                    }

                    console.log(simpleArray)
                    console.log(simpleArray2)
                  
                

The above is how we loop over a basic array. The variable name 'i' is a standard name for iteration variables within programming. Once getting into nested loops, which use 'j' and 'k' as those are the letter that are after the letter 'i'.

The length of the loop is determined by the array length, and then we just increment the value by 1.

                  
                    const years = [1989, 1990, 1991, 1992];
                    const age = [];

                    for (let i = 0; i <= years.length; i++) {
                      age.push(2023 - years[i]);
                    };
                  
                

Within the 'for loop', we can also create a new array by pushing each iteration to an already defined variable outside the loop, containing an empty array. Above is just another example of how a 'for loop' can be used.

                  
                    for (let i = 0; i <= simpleArray.length; i++) {
  
                      if (typeof simpleArray[i] !== 'string') continue;
                      console.log(simpleArray[i], typeof simpleArray[i]);
                    }
                  
                

The 'Continue' keyword allows us to break out the current iteration and move to the next. Above is an example, that it only logs certain data types.

                  
                    for (let i = 0; i <= simpleArray.length; i++) {
  
                      if (typeof simpleArray[i] === 'boolean') break;
                      console.log(simpleArray[i], typeof simpleArray[i]);
                    }
                  
                

The 'Break' keyword on the other hand breaks out of the loop entirely. Above, if a certain type is reached, it will completely stop the 'for loop ', in this instance, a number.

Lecture 47 — Assignment

Practice Assignment

  1. Let's bring back the 'populations' array from a previous assignment.

  2. Use a for loop to compute an array called 'percentages2' containing the percentages of the world population for the 4 population values. Use the function 'percentageOfWorld1' that you created earlier.

  3. Confirm that 'percentages2' contains exactly the same values as the 'percentages' array that we created manually in the previous assignment, and reflect on how much better this solution is.

                  
                    const percentageOfWorld1 = function (population) {
                      return (population / 7900) * 100;
                    }

                    const populations = [7, 60, 320, 50];
                    const percentages = [
                      percentageOfWorld1(populations[0]),
                      percentageOfWorld1(populations[1]),
                      percentageOfWorld1(populations[2]),
                      percentageOfWorld1(populations[3])
                    ];
                    const percentages2 = [];

                    for (let i = 0; i < populations.length; i++) {
                      percentages2.push(percentageOfWorld1(populations[i]));
                      console.log(`Percentage 1: ${percentages[i]} Vs. Percentage 2: ${percentages2[i]}`)
                    }
                  
                
Lecture 48

Looping backwards and loops in loops

                  
                    const myNumbers = [1, 2, 3, 4, 5];

                    for (let i = myNumbers.length - 1; i >= 0; i--) {
                      console.log(`Index Number: ${i}, Array Value: ${myNumbers[i]}`);
                    }
                  
                

To loop backwards over an array, we simply let 'i' equal to the array.length -1 and of course set the condition to be greater than or equal to 0 and lastly decrement the variable.

                  
                    for (let i = 1; i <= 3; i++) {
                      console.log(`Exercise ${i}`);
                      for (let j = 1; j <= 2; j++) {
                        console.log(`   Exercise ${i}, Rep ${j}`)
                      }
                    }
                  
                

To loop within a loop, we simply add a loop inside it.

Lecture 48 — Assignment

Practice Assignment

  1. Store this array of arrays into a variable called 'listOfNeighbours' [['Canada', 'Mexico'], ['Spain'], ['Norway', 'Sweden', 'Russia']];

  2. Log only the neighbouring countries to the console, one by one, not the entire arrays. Log a string like 'Neighbour: Canada' for each country.

  3. You will need a loop inside a loop for this. This is actually a bit tricky, so don't worry if it's too difficult for you! But you can still try to figure this out anyway.

                  
                    const listOfNeighbours = [
                      ['Canada', 'Mexico'], 
                      ['Spain'], 
                      ['Norway', 'Sweden', 'Russia']
                    ];

                    for (let i = 0; i < listOfNeighbours.length; i++) {
                      for (let j = 0; j < listOfNeighbours[i].length; j++) {
                        console.log(`Neighbour: ${listOfNeighbours[i][j]}`);
                      }
                    }
                  
                
Lecture 49

The while loop

                  
                    // basic while loop example

                    let i = 0;

                    while (i <= 10) {
                      console.log(`Loop (${i})`)
                      i++
                    };

                    // Dice game example

                    const diceMe = function (number) {
                      let dice = Math.trunc(Math.random() * number) + 1;
                    
                      while (dice !== number) {
                        console.log(`You Rolled a ${dice}`)
                        dice = Math.trunc(Math.random() * number) + 1;
                      
                        if (dice === number) console.log(`Yay!, You rolled a ${dice}, Game Over`);
                      }
                    }

                    diceMe(5);
                  
                

A while loop does not require a counter, and is used when you do not know when the loop should end. That's when something is truly random. When we know when the loop should end, it's best to use a 'for loop'.

Lecture 49 — Assignment

Practice Assignment

  1. Recreate the challenge from the lecture 'Looping Arrays, Breaking and Continuing', but this time using a while loop (call the array 'percentages3')

  2. Reflect on what solution you like better for this task: the for loop or the while loop?

                  
                    const percentageOfWorld1 = function (population) {
                      return (population / 7900) * 100;
                    }

                    const populations = [7, 60, 320, 50];

                    // For loop
                    const percentages2 = [];

                    for (let i = 0; i < populations.length; i++) {
                      percentages2.push(percentageOfWorld1(populations[i]));
                      console.log(`Percentage 2: ${percentages2[i]}`)
                    }

                    // While Loop
                    const percentages3 = [];

                    let i = 0;
                    while (i < populations.length) {
                      percentages3.push(percentageOfWorld1(populations[i]));
                      console.log(`Percentage 3: ${percentages3[i]}`);
                      i++
                    }
                  
                
Lecture 50

Coding challenge - 4

Let's improve Steven's tip calculator even more, this time using loops!

Your Tasks:
  1. Create an array 'bills' containing all 10 test bill values.

  2. Create empty arrays for the tips and the totals ('tips' and 'totals').

  3. Use the 'calcTip' function we wrote before (no need to repeat) to calculate tips and total values (bill + tip) for every bill value in the bills array. Use a for loop to perform the 10 calculations!.

Test Data:
  • 22, 295, 176, 440, 37, 105, 10, 1100, 86 and 52

Hints:
  • Call ‘calcTip ‘in the loop and use the push method to add values to the tips and totals arrays 😉

                  
                    const calcTip = function (bill) {
                      return bill >= 50 && bill <= 300 ? bill * 0.15 : bill * 0.20;
                    };

                    const bills = [22, 295, 176, 440, 37, 105, 10, 1100, 86, 52];
                    const tips = [];
                    const total = [];

                    for (let i = 0; i < bills.length; i++) {
                      tips.push(calcTip(bills[i]));
                      total.push(bills[i] + tips[i]);
                      console.log(`Bill (${i + 1}) has a total of (${total[i]}) and the Tip was (${tips[i]}) and the Bill was (${bills[i]})`);
                    }
                  
                
Bonus:

Write a function 'calcAverage' which takes an array called 'arr' as an argument. This function calculates the average of all numbers in the given array. This is a difficult challenge (we haven't done this before)! Here is how to solve it:

Bonus Tasks:
  1. First, you will need to add up all values in the array. To do the addition, start by creating a variable 'sum' that starts at 0. Then loop over the array using a for loop. In each iteration, add the current value to the 'sum' variable. This way, by the end of the loop, you have all values added together.

  2. To calculate the average, divide the sum you calculated before by the length of the array (because that's the number of elements)

  3. Call the function with the 'totals' array

                  
                    const calcAverage = function (arr) {
                      let sum = 0;
                      for (let i = 0; i < arr.length; i++) {
                        sum += arr[i];
                      }
                      return sum / arr.length;
                    }
                    
                    console.log(calcAverage(totals))