Single-page apps (Angular, Vue, React with routing/state management),
complex UIs.
Key takeaway:
Libraries: Tools you use within your code.
Frameworks: Structures you build your code within.
History
Part One: Functions in Modern JavaScript
Lesson Objectives:
Function expression and Function Hoisting
How Closure Works
Understand anonymous functions and their usage.
Explore commonly used array methods (map, filter, reduce, etc.).
Master arrow functions and their syntax.
Destructuring with JavaScript
Learn best practices for writing functions, especially in the React ecosystem.
Programming Activities for Part One
Preliminary Concepts
Function Expression
A function expression in JavaScript is a way to define a function as part of an expression.
// Assignment to a variable
const myFunc = function(x) { return x * 2; }; // Anonymous function expression
const multiply = function double(x) { return x * 2; }; // Named function expression
// As an argument to another function (callbacks)
const numbers = [1, 2, 3];
const doubled = numbers.map(function(num) { return num * 2; }); // Function expression as callback
// An arrow function syntax (a concise form of function expression)
const square = (x) => x * x; // Arrow function expression
Function Hoisting
Function hoisting is a JavaScript behavior where function declarations are conceptually moved to the top of their scope before the code is executed.
// function hoisting
hoistedFunction(); // This works!
function hoistedFunction() {
console.log("This function is hoisted.");
}
// functionExpression(); // This would cause an error: "functionExpression is not defined"
const functionExpression = function() {
console.log("Function expressions are NOT hoisted.");
};
hoistedFunction(); // This also works.
Closure
A closure in JavaScript is a function that has access to variables from an enclosing (lexical) scope, even after the outer function has finished executing.
// closure
function outerFunction() {
const outerVar = "Hello from outer";
let count=0
function innerFunction() {
count++;
console.log(outerVar); // Accessing outerVar from the outer function
console.log(count); // Accessing innerVar from the inner function
}
return innerFunction; // Returning the inner function (the closure)
}
const myCount1 = outerFunction(); // myCount1 now holds the innerFunction
myCount1(); // Output: 1
myCount1(); // Output: 2
Advanced Closure Module Pattern with Data Privacy Encapsulation
The Advanced Closure Module Pattern enhances the classic module pattern by leveraging closures for robust data privacy and encapsulation.
// closure-advanced.js
const createDog = function (name) { // Outer function: takes the pet's initial name
let breed; // Private variable to store the pet's breed(initially undefined)
function setName(newName) { // Inner function: sets the pet's name
name = newName; // Modifies the 'name' variable in the outer function's scope (closure)
}
function getName() { // Inner function: gets the pet's name
return name; // Accesses the 'name' variable from the outer function's scope (closure)
}
function setBreed(newBreed) { // Inner function: sets the pet's breed
breed= newBreed; // Modifies the 'breed' variable in the outer function's scope (closure)
}
function getBreed() { // Inner function: gets the pet's sex
return breed; // Accesses the 'breed' variable from the outer function's scope (closure)
}
// This is the core of the module pattern. It returns a function.
return function (password) { // This inner function takes a password
if (password === "pets") { // Checks if the provided password is correct
return { // If the password is correct, it returns an object.
setName, // This object contains the inner functions, effectively making them public.
getName, // These functions have closure over 'name' and 'breed'.
setBreed,
getBreed,
};
} else {
return console.log("Error, incorrect password!"); // If the password is wrong, it logs an error.
}
};
};
// Usage:
// correct password
//const getAccessToFluffy = createDog("Fluffy"); // Create a "dog creator" for Fluffy. It does NOT give access yet.
//const fluffy = getAccessToFluffy("pets"); // Call the returned function with the correct password to get access.
const fluffy = createDog("Fluffy")("pets")
if (fluffy) { // Check to make sure we got access (password was correct)
console.log(fluffy.getName()); // "Fluffy"
fluffy.setName("Fluffball");
console.log(fluffy.getName()); // "Fluffball"
fluffy.setBreed("Poodle");
console.log(fluffy.getBreed()); // "Poodle"
}
//wrong password
const getAccessToRover = createDog("Rover");
const rover = getAccessToRover("wrongpassword"); // Incorrect password
if (!rover) {
console.log("No access to Rover because of wrong password")
}
Activity 1: Using Anonymous Functions
What are Anonymous Functions?
Functions without a name.
Often used as callbacks in JavaScript.
Hands-On Example:
Open your React project and modify a component as follows:
The destructuring assignment syntax is an expression that makes it possible to unpack values from arrays or properties from objects. It's a very common and useful feature in modern JavaScript.
// Array destructuring:
const numbers = [1, 2, 3];
// Traditional way:
const first = numbers[0]; // first = 1
const second = numbers[1]; // second = 2
const third = numbers[2]; // third = 3
// With destructuring:
const [a, b, c] = numbers; // a = 1, b = 2, c = 3
// Skipping elements:
const [, , d] = numbers; // d = 3 (skips the first two elements)
// Rest operator with ... (spread) operator:
const [e, ...rest] = numbers; // e = 1, rest = [2, 3]
// Object destructuring:
const person = {
name: "Alice",
age: 30,
city: "New York"
};
// Traditional way:
const personName = person.name; // personName = "Alice"
const personAge = person.age; // personAge = 30
// With destructuring:
const { name, age, city } = person; // name = "Alice", age = 30, city = "New York"
// Renaming properties:
const { name: userName, age: userAge } = person; // userName = "Alice", userAge = 30
// Default values:
const { country = "USA" } = person; // country = "USA" (since 'country' is not in the object)
// Nested object destructuring:
const student = {
info: {
name: "Bob",
age: 20
}
};
const { info: { name: studentName } } = student; // studentName = "Bob"
// Combined array and object destructuring:
const data = [
{ id: 1, name: "Product A" },
{ id: 2, name: "Product B" }
];
const [{ name: productName1 }, { name: productName2 }] = data; // productName1 = "Product A", productName2 = "Product B"
console.log(a, b, c);
console.log(d);
console.log(e, rest);
console.log(name, age, city);
console.log(userName, userAge);
console.log(country);
console.log(studentName);
console.log(productName1, productName2);
Anatomy of main.jsx
open Chrome Developer Tools (by CTRL+SHIFT+I (or F12 key) and open Console to explore console log output.
// main.jsx
import { createElement } from "react"
import { createRoot } from "react-dom/client"
//import ReactDom from 'react-dom/client'
const root = createRoot(document.getElementById("root"))
const reactElement = createElement("h1", null, "Hello from createElement!")
console.log(reactElement)
root.render(
reactElement
)
Key Takeaways for Students
Modern JavaScript features, such as arrow functions, anonymous functions, and array methods, are essential for writing React components effectively.
Master asynchronous programming techniques, as React often involves handling async tasks (e.g., API calls).
Refactor code for clarity and maintainability, using async/await when possible.
Why React?
Lego Bricks Block Build
Vanilla JavaScrpt vs React
// index.html
<html>
<body>
<div id="app">
<script type="text/javascript">
const app = document.getElementById('app');
// creates a new h1 element
const header = document.createElement('h1');
// create a new text node for the h1 element
const headerContent = document.createTextNode(
'This is my web application!');
// append the text to the h1 element
header.appendChild(headerContent);
// place the h1 element inside the div
app.appendChild(header);
</script>
</div>
</body>
</html>
React's popularity stems from a combination of factors that make it a compelling choice for web development:
Component-Based Architecture: This promotes code reusability, organization, and maintainability, especially in large applications.
Virtual DOM: This enhances performance by minimizing direct manipulations to the actual DOM, leading to faster rendering and smoother user experiences.
Large and Active Community: This provides ample resources, libraries, and support for developers.
JSX: This syntax extension allows developers to write HTML-like code within JavaScript, making UI development more intuitive. It allows to create easily reusable and interchangeable "pieces of of the web" that can be combined in various ways to create complex systems
Strong Focus on UI: React excels at building interactive and dynamic user interfaces.
Declarative Programming : Focuses on what the program should do, and describes the desired outcome without specifying how to achieve it.
In short, React offers a powerful, efficient, and developer-friendly way to build modern web applications.