Unit 4 Notes
Unit 4 Notes
JavaScript functions are essential building blocks of the language, allowing code to be
executed when called. Functions in JavaScript can be categorized into several types based on
how they are defined and invoked. Here’s an explanation of the different types of JavaScript
functions.
A function declaration is the most common way of defining a function. It has a name and is
hoisted to the top of the scope during the execution phase.
Syntax:
function functionName(parameters) {
// function body
return value;
}
Example:
function greet(name) {
console.log(`Hello, ${name}!`);
}
greet("Alice"); // Output: Hello, Alice!
Key Points:
Function is hoisted, meaning you can call it before it's defined in the code.
Functions are block-scoped.
Syntax:
Example:
Key Points:
3. Arrow Function
Arrow functions provide a shorter syntax for writing functions. They are anonymous and do
not have their own this context, making them more suitable for certain situations, such as
inside callbacks.
Syntax:
Example:
Key Points:
Concise syntax with implicit return (if only one expression in body).
Arrow functions don’t have their own this value — they inherit this from the
outer context.
An IIFE is a function that is defined and then immediately executed. It's often used to create
local scopes to avoid polluting the global namespace.
Syntax:
(function() {
// function body
})();
Example:
(function() {
console.log("This function runs immediately!");
})();
Key Points:
5. Constructor Function
Syntax:
Key Points:
6. Generator Function
A generator function allows you to define an iterative function that can yield multiple
values on demand. The function pauses its execution and can be resumed later.
Syntax:
function* generatorFunction() {
yield value1;
yield value2;
}
Example:
function* counter() {
let count = 0;
while (count < 3) {
yield count;
count++;
}
}
const gen = counter();
console.log(gen.next().value); // Output: 0
console.log(gen.next().value); // Output: 1
console.log(gen.next().value); // Output: 2
Key Points:
7. Recursive Function
A recursive function is one that calls itself. It is useful for solving problems that can be
broken down into smaller subproblems, such as calculating factorials, traversing trees, etc.
Syntax:
function recursiveFunction() {
// Base case to stop recursion
// Recursive case to call itself
}
Example:
function factorial(n) {
if (n === 0) return 1; // Base case
return n * factorial(n - 1); // Recursive case
}
console.log(factorial(5)); // Output: 120
Key Points:
An async function is a function that always returns a Promise. It allows the use of await to
pause execution until a Promise is resolved.
Syntax:
Example:
Key Points:
async makes the function return a Promise.
await pauses execution until the Promise resolves.
A function can be defined with default values for parameters. If a value is not provided when
calling the function, the default value is used.
Syntax:
Example:
Key Points:
Syntax:
function sum(...numbers) {
return numbers.reduce((acc, num) => acc + num, 0);
}
Example:
Key Points:
Conclusion
JavaScript provides a variety of ways to define and use functions, each suited for different
scenarios:
Each function type offers distinct advantages and can be used in various contexts depending
on the needs of the program.
In JavaScript, String and Array are both objects that are used to store and manipulate data.
Each provides a set of methods and properties that help perform operations like modifying
content, extracting parts, and iterating over values.
Let's break down each of these objects and their key features:
A String in JavaScript is a sequence of characters used to represent textual data. The String
Object is a built-in JavaScript object that allows you to manipulate, search, and format
strings.
String Object and Array Object in JavaScript are both powerful tools for handling textual
and list data
, respectively.
The String Object provides methods to manipulate and extract substrings, change
case, search for patterns, and more.
The Array Object allows you to store and manipulate ordered data, with methods to
add, remove, and iterate through elements, making it ideal for tasks involving lists and
collections.
By understanding the features and methods of both the String and Array objects, you can
leverage JavaScript to handle a wide variety of data manipulation tasks efficiently.
In TypeScript, primitive data types refer to the most basic forms of data that are not objects
and do not have methods or properties. These types hold a single value and are immutable
(their values cannot be changed once assigned). TypeScript includes the following primitive
data types:
1. Number
2. String
3. Boolean
4. Symbol
5. Null
6. Undefined
7. BigInt
Each of these types serves a specific purpose, and understanding them is essential for writing
efficient TypeScript code. Let’s dive deeper into each of these types with examples.
1. Number
The number type in TypeScript represents both integer and floating-point numbers. It can also
handle special values like NaN (Not-a-Number), Infinity, and -Infinity.
Example:
Key Points:
In TypeScript, number is used for all numeric values (both integers and floating-point
numbers).
Operations like addition, subtraction, multiplication, and division work as expected.
2. String
The string type represents sequences of characters (text). Strings can be defined using
single quotes ('), double quotes ("), or backticks (`) for template literals.
Example:
Key Points:
3. Boolean
The boolean type represents logical values: either true or false. This type is commonly
used for flags or conditions in decision-making processes.
Example:
Key Points:
4. Symbol
A symbol is a unique and immutable primitive value that is often used as an identifier for
object properties. Symbols are primarily used when you need to create unique property keys
that won’t conflict with other properties.
Example:
Key Points:
Symbols are always unique, even if they have the same description.
They are mainly used for creating unique property keys in objects, ensuring there
are no accidental property name conflicts.
5. Null
The null type represents the intentional absence of any object value. It's used when you
explicitly want to indicate that a variable has no value.
Example:
Key Points:
6. Undefined
Example:
Key Points:
undefined typically means a variable has been declared but hasn’t been assigned a
value.
It is distinct from null, which is an explicit assignment of an empty or missing value.
7. BigInt
The BigInt type was introduced to handle large integers that exceed the number range.
Unlike regular numbers, BigInt can represent arbitrarily large integers.
Example:
Key Points:
BigInt is used when dealing with very large integers that cannot be accurately
represented by the number type.
BigInt literals are written with an n suffix (e.g., 123n).
Conclusion
In TypeScript, primitive data types are the building blocks of data representation and
manipulation. They are simple, immutable values that don’t have methods or properties.
Here’s a summary of the main primitive data types:
Understanding these primitive types and how to use them in your TypeScript code is
fundamental to building robust and efficient applications.
In modern JavaScript (ES6) and TypeScript, both destructuring and spread operators are
powerful features that allow for more concise, readable, and flexible code. These two features
simplify handling arrays and objects, improving both performance and developer
productivity.
1. Destructuring
Destructuring is a shorthand syntax used to unpack values from arrays or properties from
objects into distinct variables. It allows us to extract values from arrays and objects in a way
that is both clean and concise.
Array Destructuring
Array destructuring enables you to unpack values from an array into individual variables in a
single step.
Syntax:
let [variable1, variable2, ...rest] = array;
Example:
let numbers: number[] = [10, 20, 30];
// Destructuring array
let [first, second, third] = numbers;
console.log(first); // Output: 10
console.log(second); // Output: 20
console.log(third); // Output: 30
Key Points:
The variables on the left must match the order and number of elements in the array.
You can skip elements by leaving empty spots in the array, e.g., [first, , third]
will skip the second element.
The ... (rest syntax) allows collecting the remaining elements of the array into a new
array.
console.log(first); // Output: 10
console.log(second); // Output: 20
console.log(others); // Output: [30, 40, 50]
Object Destructuring
Object destructuring allows you to unpack properties from objects into variables.
Syntax:
let {property1, property2, ...rest} = object;
Example:
let person = { name: "Alice", age: 25, occupation: "Developer" };
// Destructuring object
let { name, age } = person;
Key Points:
Property names must match the variable names on the left-hand side.
You can rename variables using the : syntax if you want different names for your
variables.
You can assign default values to variables when destructuring, in case the property is
undefined.
2. Spread Operator
The spread operator (...) is used to expand elements from an array or object. It allows you
to "spread" the elements into a new array or object, making it easier to copy, merge, or
expand data.
Syntax:
let newArray = [...existingArray];
Example:
let numbers: number[] = [1, 2, 3];
let moreNumbers: number[] = [4, 5, ...numbers, 6];
Key Points:
The spread operator can also be used to copy properties from one object to another or to
merge objects.
Syntax:
let newObject = { ...existingObject };
Example:
let person = { name: "Alice", age: 25 };
let updatedPerson = { ...person, occupation: "Developer" };
Key Points:
Merging objects:
let person = { name: "Alice", age: 25 };
let job = { occupation: "Developer", company: "Tech Corp" };
let merged = { ...person, ...job };
console.log(merged); // Output: { name: "Alice", age: 25, occupation:
"Developer", company: "Tech Corp" }
Shallow Copy: The spread operator creates a shallow copy of the object. If the object
has nested objects, those nested objects are still referenced, not cloned.
copy.person.name = "Bob";
You can use both the destructuring and spread operators together to create powerful and
flexible code.
Cleaner and more readable code: These operators allow you to write less code
while performing complex operations like copying, merging, and extracting values.
Avoiding side effects: With the spread operator, you can copy data or merge objects
without mutating the original data.
Ease of use in functions: Destructuring can simplify function parameters, allowing
you to unpack properties from objects or arrays easily.
greet({ name: "Alice", age: 25 }); // Output: Hello Alice, you are 25
years old.
Conclusion
Both destructuring and the spread operator are essential features in modern JavaScript and
TypeScript development.
Destructuring allows for cleaner code by enabling you to unpack arrays and objects
into variables with minimal syntax.
The spread operator is useful for copying or merging arrays and objects in a simple
and effective way.
Together, these features significantly improve code readability, reduce verbosity, and help
prevent errors, making them a staple in modern JavaScript and TypeScript development.
5.How to let the function find the sum of two arguments and return the result
To create a function that finds the sum of two arguments and returns the result in JavaScript
or TypeScript, you can follow this simple approach:
Steps:
// Example usage
let result = sum(3, 4); // Calling the function with arguments 3 and 4
console.log(result); // Output: 7
Explanation:
sum(a: number, b: number): This is the function declaration. The parameters a and
b are both of type number, ensuring that the function only accepts numbers.
return a + b;: This line performs the addition of the two arguments (a and b) and
returns the result.
let result = sum(3, 4);: This calls the function with the arguments 3 and 4,
storing the return value in the variable result.
console.log(result);: This prints the result to the console, which in this case
would be 7.
Additional Notes:
The function is very flexible; you can pass any two numbers to it, and it will return
their sum.
The function ensures type safety by specifying that both parameters must be numbers
(a: number, b: number).
This is a concise, clear, and effective way to define a function that calculates the sum of two
numbers
In TypeScript, ambient functions are a concept that allows you to declare the existence of
functions (or variables) that are provided by external sources, without providing their actual
implementation. They serve as a way to inform TypeScript about the types of functions or
objects that exist outside of the TypeScript codebase, typically coming from external
libraries, JavaScript code, or global environments.
Ambient functions are mainly used when you're working with code that is not written in
TypeScript but you want TypeScript to understand the types and signatures of these
functions.
To declare an ambient function, the declare keyword is used. This keyword tells TypeScript
that the function exists and its type signature, but it doesn't provide an implementation.
Syntax:
Example:
Let's say you are working with an external JavaScript library or a global browser function
that isn't written in TypeScript. Here's how you might declare an ambient function:
In this example:
Real-World Example:
The browser provides a global setTimeout() function. Here's how we can declare it:
If you are using an external JavaScript library, like jQuery, that doesn't come with TypeScript
type definitions, you might want to declare an ambient function.
This declares a function $, which you might use as part of the jQuery library. The
function takes a string (selector) and returns a generic type T that is determined at
runtime based on how the function is used.
1. Global Functions:
Ambient functions are particularly useful for declaring globally available functions
that are part of the runtime environment, such as browser APIs (alert(),
console.log()), Node.js APIs (process.exit()), or third-party libraries.
2. Integration with JavaScript Libraries:
When integrating TypeScript with JavaScript libraries that do not have type
definitions, you can declare ambient functions to provide type safety for the library's
API.
3. Third-Party Modules Without Type Definitions:
In cases where a third-party module or API does not provide TypeScript definitions,
you can declare the module’s functions using the declare keyword to avoid type
errors during development.
If you're working with a global function in your environment that TypeScript doesn't know
about, such as a function defined in another script or in a non-TypeScript environment:
1. Type Safety:
Ambient functions allow TypeScript to understand and type-check the arguments and
return values, improving safety when working with external or non-TypeScript code.
2. Avoid Errors:
By declaring ambient functions, you avoid runtime errors and ensure that you are
calling these functions with the correct types and parameters.
3. Improved Development Experience:
TypeScript can offer autocompletion, type inference, and error checking for these
ambient functions, improving the developer experience when working with external
libraries or global APIs.
Conclusion:
In TypeScript, ambient functions are a way to declare functions that are defined outside of
your current codebase (such as global browser functions or third-party libraries). They allow
TypeScript to recognize and type-check functions that are already available in the runtime
environment but are not part of the current TypeScript code. By using the declare keyword,
developers can leverage external JavaScript code while maintaining strong typing in
TypeScript.
TypeScript, being a superset of JavaScript, provides all the loop structures and function
syntax available in JavaScript, with additional type-checking benefits. Below, we will explain
the different loops and functions in TypeScript.
1. Loops in TypeScript
Loops in TypeScript are used to execute a block of code repeatedly under certain conditions.
TypeScript supports all JavaScript loop structures, including for, while, and do...while.
The major difference with TypeScript is that you can specify types for variables used in the
loops.
a. for loop
The for loop is the most commonly used loop. It consists of three parts:
Syntax:
b. while loop
A while loop executes as long as the condition is true. It first checks the condition before
entering the loop.
Syntax:
let i = 0;
while (i < 5) {
console.log(i); // Output: 0, 1, 2, 3, 4
i++;
}
c. do...while loop
The do...while loop is similar to the while loop, but it executes the block of code at least
once before checking the condition.
Syntax:
let i = 0;
do {
console.log(i); // Output: 0, 1, 2, 3, 4
i++;
} while (i < 5);
The condition is checked after the code block is executed, ensuring that the loop runs
at least once.
d. for...in loop
The for...in loop is used to iterate over the keys (indices) of an object or array.
Syntax:
e. for...of loop
The for...of loop is used to iterate over iterable objects (such as arrays, strings, etc.) by
accessing their values.
Syntax:
2. Functions in TypeScript
Functions in TypeScript allow us to define reusable blocks of code. TypeScript builds upon
JavaScript's function syntax and adds type annotations for function parameters and return
values to ensure type safety.
a. Function Declaration
A function declaration defines a function with a name, a list of parameters, and a block of
code to execute.
Syntax:
Parameter Type Annotation: name: string ensures that name is always a string.
Return Type Annotation: : string ensures the function returns a string.
b. Function Expression
Syntax:
c. Optional Parameters
TypeScript allows you to define function parameters as optional using the ? symbol.
Syntax:
function greet(name: string, age?: number): string {
if (age) {
return `Hello, ${name}. You are ${age} years old.`;
}
return `Hello, ${name}!`;
}
The age parameter is optional, so the function can be called with just name.
d. Default Parameters
Syntax:
Here, age has a default value of 18. If not provided, 18 will be used.
e. Rest Parameters
Syntax:
The ...numbers: number[] allows the function to accept any number of numeric
arguments, which are then stored in an array.
Conclusion
Loops: TypeScript supports all basic JavaScript loops (for, while, do...while,
for...in, and for...of) along with the ability to specify the types of variables used
in loops for added safety and clarity.
Functions: Functions in TypeScript extend JavaScript's capabilities by providing
strong typing for parameters and return values. TypeScript also introduces features
like optional parameters, default values, and rest parameters to enhance flexibility and
maintainability.