Topic:
FundamentalsStrict mode, functions, arrows, arrays, objects, and coding challenges.
- 32. Activating Strict Mode
- 33. Functions
- 34. Function Declarations vs. Expressions
- 35. Arrow Functions
- 36. Functions Calling Other Functions
- 37. Reviewing Functions
- 38. Coding Challenge 1
- 39. Introduction to Arrays
- 40. Basic Array Operations (Methods)
- 41. Coding Challenge ##2
- 42. Introduction to Objects
- 43. Dot vs. Bracket Notation
- 44. Object Methods
- 45. Coding Challenge ##3
- 46. Iteration: The for Loop
- 47. Looping Arrays, Breaking and Continuing
- 48. Looping Backwards and Loops in Loops
- 49. The while Loop
- 50. Coding Challenge ##4
📝 Why Strict Mode? Before ES5 (2009), JavaScript silently ignored many errors to keep websites running. While forgiving, this made debugging a nightmare. Strict mode opts into a less forgiving but safer subset of JavaScript that catches common mistakes and disables legacy features.
What Strict Mode Prevents:
- Using variables without declaring them (
x = 3throws ReferenceError) - Assigning to read-only properties
- Deleting variables, functions, or function arguments
- Duplicate parameter names
- Using reserved words as variable names (
interface,private,package)
💡 Best Practice: Always start every script with
'use strict';. In modern ES6 modules, strict mode is enabled automatically.
'use strict'; // Activates strict mode for the entire script- Always put strict mode in the beginning of the file
- It makes it easier for developer to avoid accidental errors.
First, strict mode forbids us to do certain things and second, it will actually create visible errors for us in certain situations in which without strict mode JavaScript will simply fail silently without letting us know that we did a mistake.
'use strict';
let hasDriversLicense = false;
const passTest = true;
if (passTest) hasDriversLicense = true; // if in hasDriver(s)License s is missing the code will behave unexpectedly
if (hasDriversLicense) console.log('I can drive :D');
// Const interface = 'Audio'; // Uncaught SyntaxError: Missing initializer in const declaration
// Const private = 534; // Uncaught SyntaxError: Missing initializer in const declaration📝 What is a Function? A function is a reusable block of code designed to perform a specific task. Functions are the fundamental building blocks of JavaScript programs — they help you organize code, avoid repetition, and build abstractions.
Function Anatomy:
function name(parameter1, parameter2) {
// Function body
return result;
}- Parameters are placeholders (variables) in the definition
- Arguments are the actual values passed when calling
- Return sends a value back to the caller; without it, the function returns
undefined
function logger() {
console.log('My name is xoraus');
}
// Calling / running / invoking function
logger(); // → My name is xoraus
logger(); // → My name is xoraus
logger(); // → My name is xoraus
function fruitProcessor(apples, oranges) {
const juice = `Juice with ${apples} apples and ${oranges} oranges.`;
return juice;
}
const appleJuice = fruitProcessor(10, 5);
console.log(appleJuice);1
const appleOrangeJuice = fruitProcessor(4, 8);
console.log(appleOrangeJuice);
const num = Number('6833');🎯 DRY Principle: Don't Repeat Yourself. If you find yourself writing the same code twice, extract it into a function.
💡 The Critical Difference: Function declarations are hoisted — you can call them before they're defined in the code. Function expressions are not hoisted — the variable exists but holds
undefineduntil the assignment line executes.
| Feature | Declaration | Expression |
|---|---|---|
| Syntax | function name() {} |
const name = function() {} |
| Hoisted | ✅ Yes | ❌ No |
| Can be anonymous | ❌ No | ✅ Yes |
this binding |
Own this |
Own this |
🎯 When to use which: Use declarations for standalone utility functions. Use expressions when you need to pass a function as an argument, return it from another function, or control when it becomes available.
// Function declaration
function calcAge1(birthYeah) {
return 2047 - birthYeah;
}
const age1 = calcAge1(1997);
// Function expression
const calcAge2 = function (birthYeah) { // Anonymous Functions - this function is an expression. Expressions produce value.
return 2047 - birthYeah;
}
const age2 = calcAge2(1997);
console.log(age1, age2);- Parameter: The placeholder variable in the function definition (e.g.,
applesinfruitProcessor(apples, oranges)). - Argument: The actual value passed when calling the function (e.g.,
10infruitProcessor(10, 5)). - Functions are first-class values: In JavaScript, functions can be assigned to variables, passed as arguments, and returned from other functions — just like numbers or strings.
📝 Why Arrow Functions? Introduced in ES6, arrow functions provide a concise syntax and solve the "
thisbinding" problem in callbacks. However, they come with trade-offs.
Arrow Function Rules:
- No own
this— inherits from parent scope (lexicalthis) - No
argumentsobject - Cannot be used as constructor functions (
newthrows error) - Cannot use
yield(no generator arrows) - Great for: short callbacks, array methods, event handlers where you want outer
this - Avoid for: object methods, prototype methods, event listeners needing element
this
const calcAge3 = birthYeah => 2047 - birthYeah;
const age3 = calcAge3(1997);
console.log(age3);
const yearsUntilRetirement = (birthYeah, firstName) => {
const age = 2047 - birthYeah;
const retirement = 65 - age;
// Return retirement;
return `${firstName} retires in ${retirement} years`;
}
console.log(yearsUntilRetirement(1997, 'xoraus')); console.log(yearsUntilRetirement(2005, 'ahmed'));function cutFruitPieces(fruit) {
return fruit * 4;
}
function fruitProcessor(apples, oranges) {
const applePieces = cutFruitPieces(apples);
const orangePieces = cutFruitPieces(oranges);
const juice = `Juice with ${applePieces} piece of apple and ${orangePieces} pieces of orange.`;
return juice;
}
console.log(fruitProcessor(2, 3));- Arrow functions do not get the this Keyword
const calcAge = function (birthYeah) {
return 2047 - birthYeah;
}
const yearsUntilRetirement = function (birthYeah, firstName) {
const age = calcAge(birthYeah);
const retirement = 65 - age;
if (retirement > 0) {
console.log(`${firstName} retires in ${retirement} years`);
return retirement;
} else {
console.log(`${firstName} has already retired 🎉`);
return -1;
}
}
console.log(yearsUntilRetirement(1997, 'xoraus'));
console.log(yearsUntilRetirement(1980, 'Jordan'));🖼️ Visual: JavaScript Fundamentals Part 2
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!
- Create an arrow function 'calcAverage' to calculate the average of 3 scores
- Use the function to calculate the average for both teams
- 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)".
- Use the 'checkWinner' function to determine the winner for both DATA 1 and DATA 2.
- Ignore draws this time.
TEST DATA 1: Dolphins score 44, 23 and 71. Koalas score 65, 54 and 49 TEST DATA 2: Dolphins score 85, 54 and 41. Koalas score 23, 34 and 27
HINT: To calculate average of 3 values, add them all together and divide by 3 HINT: To check if number A is at least double number B, check for A >= 2 * B. Apply this to the team's average scores 😉
calcAverage = (scoreA, scoreB, scoreC) => (scoreA, scoreB, scoreC) / 3
const teamDolphinAvg = Math.floor(calcAverage(85,54,41));
const teamKoalaAvg = Math.floor(calcAverage(23,34,27));
console.log(teamDolphinAvg,teamKoalaAvg)
function checkWinner(teamDolphinAvg,teamKoalaAvg) {
if (teamDolphinAvg >= 2 * teamKoalaAvg) {
console.log(`Dolphins win 🏆 ${teamDolphinAvg} vs ${teamKoalaAvg}`)
} else if (teamKoalaAvg >= 2 * teamDolphinAvg) {
console.log(`Koalas win 🏆 ${teamKoalaAvg} vs. ${teamDolphinAvg}`)
} else {
console.log(`No body won :(`)
}
}
checkWinner(800,351)
// Test 2
scoreDolphins = calcAverage(85, 54, 41);
scoreKoalas = calcAverage(23, 34, 27);
console.log(scoreDolphins, scoreKoalas);
checkWinner(scoreDolphins, scoreKoalas);💡 Arrays vs. Objects: Use an array when you need an ordered collection of values (a list). Use an object when you need labeled/keyed properties (a dictionary/map).
| Use Array When... | Use Object When... |
|---|---|
| Order matters | Order doesn't matter |
| You iterate over all items | You look up by name |
| You need stack/queue behavior | You need named properties |
| Data is homogeneous | Data is heterogeneous |
const friend1 = 'Al-Farabi';
const friend2 = 'Al-Ghazali';
const friend3 = 'Al- Razi';
const friends = ['Al-Farabi', 'Al-Ghazali', 'Al- Razi'];
console.log(friends);
const y = new Array(1991, 1984, 2008, 2020);
console.log(friends[0]); // → Al-Farabi
console.log(friends[2]); // → Al- Razi
console.log(friends.length); // outpt: 3
console.log(friends[friends.length - 1]); // → Peter
friends[3] = 'Al-Qalbi';
console.log(friends); // → Al-Farabi, Al-Ghazali, Al- Razi
// Friends = ['Bob', 'Alice']
const firstName = 'Jordan';
const xoraus = [firstName, 'Ahmed', 2047 - 1997, 'teacher', friends];
console.log(xoraus);
console.log(xoraus.length);
// Exercise
const calcAge = function (birthYeah) {
return 2047 - birthYeah;
}
const years = [1990, 1967, 2002, 2010, 2018];
const age1 = calcAge(years[0]);
const age2 = calcAge(years[1]);
const age3 = calcAge(years[years.length - 1]);
console.log(age1, age2, age3);
const ages = [calcAge(years[0]), calcAge(years[1]), calcAge(years[years.length - 1])];
console.log(ages);const friends = ['Al-Farabi', 'Al-Ghazali', 'Al- Razi'];
// Const friends = ['Michael', 'Steven', 'Peter'];
// Add elements
const newLength = friends.push('xoraus');
console.log(friends);
console.log(newLength);
friends.unshift('Jordan');
console.log(friends);
// Remove elements
friends.pop(); // Last
const popped = friends.pop();
console.log(popped);
console.log(friends);
friends.shift(); // First
console.log(friends);
console.log(friends.indexOf('Al-Farabi'));
console.log(friends.indexOf('Al-Ghazali'));
friends.push(25);
console.log(friends.includes('Al- Razi'));
console.log(friends.includes('Ahmed'));
console.log(friends.includes(25));
if (friends.includes('Al-Ghazali')) {
console.log('You have a friend called Al-Ghazali');
}Ahmed 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%.
- 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.
- And now let's use arrays! So create an array 'bills' containing the test data below.
- Create an array 'tips' containing the tip value for each bill, calculated from the function you created before.
- BONUS: Create an array 'total' containing the total values, so the bill + tip.
TEST DATA: 125, 555 and 44
HINT: 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.2;
}
// Const calcTip = bill => bill >= 50 && bill <= 300 ? bill * 0.15 : bill * 0.2;
const bills = [125, 555, 44];
const tips = [calcTip(bills[0]), calcTip(bills[1]), calcTip(bills[2])];
const totals = [bills[0] + tips[0], bills[1] + tips[1], bills[2] + tips[2]];
console.log(bills, tips, totals);const xorausArray = [
'Jordan',
'Ahmed',
2027 - 1997,
'teacher',
['Ali', 'Khan', 'Sal']
];
const xoraus = {
firstName: 'Jordan',
lastName: 'Ahmed',
age: 2027 - 1997,
job: 'teacher',
friends: ['Ali', 'K', 'Sal']
};const xoraus = {
firstName: 'Jordan',
lastName: 'Ahmed',
age: 2027 - 1997,
job: 'teacher',
friends: ['Plato', 'Aristotle', 'Socrates']
};
console.log(xoraus);
console.log(xoraus.lastName); // → Ahmed
console.log(xoraus['lastName']); // → Ahmed
const nameKey = 'Name';
console.log(xoraus['first' + nameKey]); // → Jordan
console.log(xoraus['last' + nameKey]); // → Ahmed
// console.log(xoraus.'last' + nameKey) // this will not work
const interestedIn = prompt('What do you want to know about Jordan? Choose between firstName, lastName, age, job, and friends');
if (xoraus[interestedIn]) {
console.log(xoraus[interestedIn]);
} else {
console.log('Wrong request! Choose between firstName, lastName, age, job, and friends');
}
xoraus.location = 'India';
xoraus['twitter'] = '@xoraus';
console.log(xoraus);
// Challenge
// "Jonas has 3 friends, and his best friend is called Aristotle"
console.log(`${xoraus.firstName} has ${xoraus.friends.length} friends, and his best friend is called ${xoraus.friends[1]}`);- when we need to first compute the property name, then we have to use the bracket notation otherwise use dot notation.
- we get **undefined ** when when we try to access a property on an object that does not exist.
const xoraus = {
firstName: 'Jordan',
lastName: 'Ahmed',
birthYeah: 1997,
job: 'Programmer',
friends: ['Socrates', 'Plato', 'Aristotle'],
hasDriversLicense: true,
// CalcAge: function (birthYeah) {
// Return 2037 - birthYeah;
// }
// CalcAge: function () {
// // console.log(this);
// Return 2027 - this.birthYeah;
// }
calcAge: function () {
this.age = 2027 - this.birthYeah;
return this.age;
},
getSummary: function () {
return `${this.firstName} is a ${this.calcAge()}-year old ${xoraus.job}, and he has ${this.hasDriversLicense ? 'a' : 'no'} driver's license.`
}
};
console.log(xoraus.calcAge());
console.log(xoraus.age);
console.log(xoraus.age);
console.log(xoraus.age);
// Challenge
// "Jonas is a 30-year old programmer, and he has a driver's license"
console.log(xoraus.getSummary());- Any function that is attached to an object is called a method.
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)
- For each of them, create an object with properties for their full name, mass, and height (Mark Miller and John Smith)
- 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.
- Log to the console who has the higher BMI, together with the full name and the respective BMI. Example: "John Smith's BMI (28.3) is higher than Mark Miller'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);
// "John Smith's BMI (28.3) is higher than Mark Miller's (23.9)!"
if (mark.bmi > john.bmi) {
console.log(`${mark.fullName}'s BMI (${mark.bmi}) is higher than ${john.fullName}'s BMI (${john.bmi})`)
} else if (john.bmi > mark.bmi) {
console.log(`${john.fullName}'s BMI (${john.bmi}) is higher than ${mark.fullName}'s BMI (${mark.bmi})`)
}// console.log('Lifting weights repetition 1 🏋️♀️');
// console.log('Lifting weights repetition 2 🏋️♀️');
// console.log('Lifting weights repetition 3 🏋️♀️');
// console.log('Lifting weights repetition 4 🏋️♀️');
// console.log('Lifting weights repetition 5 🏋️♀️');
// console.log('Lifting weights repetition 6 🏋️♀️');
// console.log('Lifting weights repetition 7 🏋️♀️');
// console.log('Lifting weights repetition 8 🏋️♀️');
// console.log('Lifting weights repetition 9 🏋️♀️');
// console.log('Lifting weights repetition 10 🏋️♀️');
// For loop keeps running while condition is TRUE
for (let rep = 1; rep <= 30; rep++) {
console.log(`Lifting weights repetition ${rep} 🏋️♀️`);
}const jonas = [
'Jonas',
'Schmedtmann',
2037 - 1991,
'teacher',
['Michael', 'Peter', 'Steven'],
true
];
const types = [];
// console.log(jonas[0])
// console.log(jonas[1])
// ...
// console.log(jonas[4])
// Jonas[5] does NOT exist
for (let i = 0; i < jonas.length; i++) {
// Reading from jonas array
console.log(jonas[i], typeof jonas[i]);
// Filling types array
// Types[i] = typeof jonas[i];
types.push(typeof jonas[i]);
}
console.log(types);
const years = [1991, 2007, 1969, 2020];
const ages = [];
for (let i = 0; i < years.length; i++) {
ages.push(2037 - years[i]);
}
console.log(ages);
// Continue and break
console.log('--- ONLY STRINGS ---')
for (let i = 0; i < jonas.length; i++) {
if (typeof jonas[i] !== 'string') continue;
console.log(jonas[i], typeof jonas[i]);
}
console.log('--- BREAK WITH NUMBER ---')
for (let i = 0; i < jonas.length; i++) {
if (typeof jonas[i] === 'number') break;
console.log(jonas[i], typeof jonas[i]);
}const jonas = [
'Jonas',
'Schmedtmann',
2037 - 1991,
'teacher',
['Michael', 'Peter', 'Steven'],
true
];
// 0, 1, ..., 4
// 4, 3, ..., 0
for (let i = jonas.length - 1; i >= 0; i--) {
console.log(i, jonas[i]);
}
for (let exercise = 1; exercise < 4; exercise++) {
console.log(`-------- Starting exercise ${exercise}`);
for (let rep = 1; rep < 6; rep++) {
console.log(`Exercise ${exercise}: Lifting weight repetition ${rep} 🏋️♀️`);
}
}for (let rep = 1; rep <= 10; rep++) {
console.log(`Lifting weights repetition ${rep} 🏋️♀️`);
}
let rep = 1;
while (rep <= 10) {
// console.log(`WHILE: Lifting weights repetition ${rep} 🏋️♀️`);
rep++;
}
let dice = Math.trunc(Math.random() * 6) + 1;
while (dice !== 6) {
console.log(`You rolled a ${dice}`);
dice = Math.trunc(Math.random() * 6) + 1;
if (dice === 6) console.log('Loop is about to end...');
}Let's improve Steven's tip calculator even more, this time using loops!
- Create an array 'bills' containing all 10 test bill values
- Create empty arrays for the tips and the totals ('tips' and 'totals')
- 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
HINT: Call calcTip in the loop and use the push method to add values to the tips and totals arrays 😉
- 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: 4.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 4.2. To calculate the average, divide the sum you calculated before by the length of the array (because that's the number of elements) 4.3. Call the function with the 'totals' array
const calcTip = function (bill) {
return bill >= 50 && bill <= 300 ? bill * 0.15 : bill * 0.2;
}
const bills = [22, 295, 176, 440, 37, 105, 10, 1100, 86, 52];
const tips = [];
const totals = [];
for (let i = 0; i < bills.length; i++) {
const tip = calcTip(bills[i]);
tips.push(tip);
totals.push(tip + bills[i]);
}
console.log(bills, tips, totals);
const calcAverage = function (arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
// Sum = sum + arr[i];
sum += arr[i];
}
return sum / arr.length;
}
console.log(calcAverage([2, 3, 7]));
console.log(calcAverage(totals));
console.log(calcAverage(tips));| Concept | Syntax / Rule |
|---|---|
| Function declaration | function name() {} |
| Function expression | const name = function() {} |
| Arrow function | const name = () => {} |
| Array literal | ['a', 'b', 'c'] |
| Object literal | {key: value} |
| For loop | for (let i = 0; i < n; i++) |
| While loop | while (condition) |
💡 Best Practice: Use arrow functions for short, one-line operations. Use regular functions for methods that need their own
this.
← 📄 01. JavaScript Fundamentals Part 1 | 🏠 Home | 📄 04. Developer Skills & Editor Setup →
Happy Coding! 🚀