https://github.com/skywalkersam/js-101
JavaScript 101
https://github.com/skywalkersam/js-101
freecodecamp javascript
Last synced: 29 days ago
JSON representation
JavaScript 101
- Host: GitHub
- URL: https://github.com/skywalkersam/js-101
- Owner: skywalkerSam
- Created: 2024-12-06T08:13:34.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-05-01T14:20:40.000Z (about 1 month ago)
- Last Synced: 2026-05-01T15:32:07.337Z (about 1 month ago)
- Topics: freecodecamp, javascript
- Language: JavaScript
- Homepage:
- Size: 9.22 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
Awesome Lists containing this project
README
# [introduction to JavaScript](https://www.freecodecamp.org/learn/javascript-v9/)
w/ freeCodeCamp.org
- **immutability** means that once something is _created_, it **cannot be changed**.
- A `function()` is a reusable block of code that performs a specific task and can be called with various inputs.
- A `method` is a _type of function_ that is associated with an `object`, meaning it operates on the data contained _within that object_.
- An `argument` is a `value` you give to a `function` or `method` when you call it, **enabling that function or method** to perform its task using the **specific information you provide**.
- A **compiler** translates high-level programming language code into **machine-readable** code, which creates an **executable** file.
## JavaScript is a Dynamically Typed Language
it means that **you don't have to specify the data type of a variable** when you declare it. The JavaScript engine **automatically determines** the data type based on the value assigned to the variable **during execution**.
```js
let error = 404; // JavaScript treats error as a number
error = "Not Found"; // JavaScript now treats error as a string
```
`Note`: The **flexibility** of **dynamic typing** makes JavaScript more **forgiving** and easy to work with for **quick scripting**, but it can also introduce **"bugs"** that may be **harder to catch**, especially as your program grows larger\*
### Statically Typed Languages
in **statically typed** languages like `C#` or `C++`, **you must declare the data type of a variable when you create it**, and that type **cannot** be _changed_.
- Other languages, like `C#`, that are **not dynamically typed** would result in an error:
```c
int error = 404; // value must always be an integer
error = "Not Found"; // This would cause an error in C#
```
`Note`: Statically typed languages enforce **stricter rules** that can **prevent certain errors before the program runs**, but they **require more upfront declaration** and offer **less flexibility** in changing _types_.
### Dynamic vs. Static
- The difference between dynamic typing and static typing lies in the **flexibility vs. the safety of your code**.
- Dynamically typed languages offer **flexibility** but at the cost of **potential runtime errors\***.
- Statically typed languages **enforce a fixed variable type**.
## `undefined` vs `null`
- `undefined` means a variable has been declared but hasn't been given a value yet.
```javascript
let thingsBe;
console.log(thingsBe); // undefined
```
- `null` means the variable has been intentionally set to "nothing" and does not hold any value.
```javascript
let go = null;
console.log(go); // null
```
## Variable Naming Conventions
1. Variable names should be **descriptive** and **meaningful**.
- it is best to **keep variable names readable** by using letters, numbers, underscores, or dollar signs.
2. They **cannot** start with a `number`. They must begin with a `letter`, an underscore (`_`), or a dollar sign (`$`).
```javascript
// invalid variable name
let 1stPlace; // starts with a number
let age;
let _score;
let $total;
```
3. Variable names should **not** contain **spaces** or **special characters**, except for `_` and `$`.
- **Do not** use special characters like, exclamation points (`!`), or at (`@`) symbols in your variable names.
4. Variable names should be `camelCase` like `cityName`, `isLoggedIn`, and `veryBigNumber`.
- in JavaScript, variable names are `case-sensitive`, meaning the word `age` in all _lowercase_ and the word `Age` with a capital `A` are considered **different** _variables_.
```javascript
let age = 25;
let Age = 30;
console.log(age); // 25
console.log(Age); // 30
```
- This is why it's **important** to stick with a consistent naming convention like `camelCase`. camelCase is where the **first word** is all **lowercase** and each **subsequent** word starts with **an uppercase** letter.
```javascript
let thisIsCamelCase;
let anotherExampleVariable;
let freeCodeCampStudents;
```
5. Variable names should **not** be **reserved keywords**.
- There are certain keywords in JavaScript that you **cannot** use as _variable_ names, such as `let`, `const`, `function`, or `return`, as they are reserved for the language _itself_.
## `let`
- The `let` keyword allows you to declare variables that can be updated or reassigned later.
```javascript
let score = 10;
console.log(score); // 10
score = 20;
console.log(score); // 20
```
## `const`
- const is used to declare variables that are **constant**.
- Once you assign a value to a variable declared with const, you **cannot reassign** it.
This makes const _ideal_ for values that **you don't want to change accidentally**, or otherwise, during the execution of the program.
```javascript
const MAX_SIZE = 100;
console.log(MAX_SIZE); // 100
// Once MAX_SIZE is assigned the value 100, it cannot be changed.
MAX_SIZE = 200; // This will result in an error
```
- Variables declared with `const` must be assigned a value at the time of declaration.
```javascript
const PI; // Error: Missing initializer in const declaration
```
- Use const when you want to declare variables that should **remain constant**, like **configuration values** or **settings** that shouldn't be changed \*accidentally\*\*
`Note`: You can also use the `var` keyword, but it's **not as recommended anymore**. The `var` is kind of like `let`, except it has a **wider scope**, which is more likely to **cause problems\*** in your _program_.
## "Strings"
A string is a **sequence of characters** wrapped in either **single quotes** (`''`), **double quotes** (`""`) or **backticks** (``).
- Strings are **primitive** data types, and they are **immutable**.
```js
let correctWay = "This is a string";
let alsoCorrect = "This is also a string";
```
- **immutability** means that once a string is **created**, you **cannot change the characters** in the string. However, you can still **reassign strings** to a _new value_.
```js
let firstName = "Sam";
firstName = "Sammy"; // Reassigning the string to a new value
```
## String Concatenation
### w/ `+`
- One disadvantage of using the `+` operator for string concatenation is that it can lead to **spacing issues** if you don't carefully manage the spacing between the concatenated strings.
- `+` operator is best for _simple concatenation_, especially when you need to combine a few strings or variables.
```javascript
let firstName = "John";
let lastName = "Doe";
let fullName = firstName + lastName;
console.log(fullName); // "JohnDoe"
```
### w/ `+=`
- if you need to **add or append** to an existing string, then you can use the `+=` operator.
- `+=` operator is useful when building up a string step by step or _appending_ new content to an existing string variable.
```javascript
let greeting = "Hello";
greeting += ", John!";
console.log(greeting); // "Hello, John!"
```
### w/ `concat()`
- `.concat()` method is beneficial when you need to _concatenate multiple strings_ together.
```javascript
let firstName = "John";
let lastName = "Doe";
let fullName = firstName.concat(" ", lastName);
console.log(fullName); // John Doe
```
## Working w/ "Strings"
In JavaScript, strings are treated as sequences of characters, and `each character` in a string can be accessed using bracket notation (`[]`). This allows you to retrieve a specific character from a string based on its **position**, which is called its `index`.
- An **index** is the **position of a character within a string**, and it is `zero-based`. This means that the **first character** of a string has an index of `0`, the **second** character has an index of `1`, and so on...
- For example, in the string `hello`, the character `h` is at index `0`, `e` is at index `1`, `l` is at index `2`, and so on...
```js
let greeting = "hello";
console.log(greeting[1]); // "e"
```
- The `length` property of a string tells you **how many characters it contains**, so to access the last character, you would subtract one from the length.
- in this case, the `length` of `hello` is `5`, and the last character (`o`) is at index `4` which is `5 - 1`.
```js
let greeting = "hello";
console.log(greeting[greeting.length - 1]); // "o"
```
## Escape Sequence Characters
### `\n` (Newline Character)
- in many programming languages, including JavaScript, you can create **a newline in a string** using a special character called an `escape sequence`. The most common escape sequence for _newlines_ is `\n`.
```js
/**
"Roses are red,
Violets are blue,
JavaScript is fun,
And so are you."
**/
let poem =
"Roses are red,\nViolets are blue,\nJavaScript is fun,\nAnd so are you.";
console.log(poem);
```
### Escaping String: `\"` (inner Quote)
```js
let statement = "She said, "Hello!""; //This will throw an error.(
let statement = "She said, \"Hello!\"";
console.log(statement); // She said, "Hello!"
```
### Escaping String: `\'` (Single Quote)
```js
let quote = "It's a beautiful day!";
console.log(quote); // It's a beautiful day!
```
`Note`: The backslash (`\`) tells JavaScript to treat the _quotes_ as **literal characters**, so they appear correctly in the output.
## Template Literals (``) & String interpolation (`${}`)
Template Strings are defined with backticks (``). They allow for **easier string manipulation**, including **embedding variables and expressions** directly inside a _string_, a feature known as **_string interpolation_**.
```js
const name = "Alice";
const age = 25;
const message = `My name is ${name} and I am ${age} years old.`;
console.log(message);
```
- Supports **multi-line** strings.
- With **regular strings**, you would need to use escape characters (`\n`) to create new lines. With **template literals**, you can simply write the string across multiple lines, and the **formatting is preserved**:
```js
let poem = `Roses are red,
Violets are blue,
JavaScript is fun,
And so are you.`;
console.log(poem);
```
- A **powerful** and **flexible** way to work with strings.
- Embed **JavaScript expressions directly within the string**, like in this example:
```js
const song = "Bohemian Rhapsody";
const score = 9.5;
const highestScore = 10;
const output = `One of my favorite songs is "${song}". I rated it ${
(score / highestScore) * 100
}%.`;
console.log(output);
```
## `indexOf()`
To **locate** the position of a **substring** inside of a _string_. it returns the **initial position** of the string starting with the index of `0`.
```js
let sentence = "JavaScript is awesome!";
let position = sentence.indexOf("awesome!");
console.log(position); // 14
```
- if the substring is **not found**, `indexOf()` returns `-1`.
```js
let sentence = "JavaScript is awesome!";
let position = sentence.indexOf("fantastic");
console.log(position); // -1
```
- You can also specify **where to begin** searching within the string by providing a **second argument** to `indexOf()`.
```js
let sentence = "JavaScript is awesome, and JavaScript is powerful!";
let position = sentence.indexOf("JavaScript", 10);
console.log(position); // 27
```
- The `indexOf()` method is **case sensitive**.
```js
console.log("freeCodeCamp".indexOf("F")); // -1
```
## `includes()` method
The `includes()` method is used to check **if a string contains a specific substring**. If the substring is found within the string, the method returns `true` otherwise, it returns `false`.
- **Case-sensitive**
```js
let phrase = "JavaScript is awesome!";
let result = phrase.includes("awesome");
console.log(result); // true
let phrase = "JavaScript is awesome!";
let result = phrase.includes("Awesome");
console.log(result); // false
```
- You can also use the `includes()` method to check for a substring starting at a specific `index` in the string by providing a second parameter:
```js
let text = "Hello, JavaScript world!";
let result = text.includes("JavaScript", 7);
console.log(result); // true
```
## `slice()` method
The `slice()` method allows you to **extract a portion of a string** and **returns a new string**, without modifying the original string.
- it takes two parameters: the **starting** index and the _optional_ **ending** index.
```js
string.slice(startIndex, endIndex);
```
```js
let message = "Hello, world!";
let greeting = message.slice(0, 5);
console.log(greeting); // Hello
```
- if you **omit the second parameter**, `slice()` will extract everything **from the start index to the end** of the string:
```js
let message = "Hello, world!";
let world = message.slice(7);
console.log(world); // world!
```
- You can also use **negative numbers as indexes**. When you use a negative number, it **counts backward from the end** of the string:
```js
let message = "JavaScript is fun!";
let lastWord = message.slice(-4);
console.log(lastWord); // fun!
```
## `toUpperCase()`
The `toUpperCase()` method **converts all the characters to uppercase** letters and **returns a new string** with all uppercase characters.
```js
let greeting = "Hello, World!";
let uppercaseGreeting = greeting.toUpperCase();
console.log(uppercaseGreeting); // "HELLO, WORLD!"
```
## `toLowerCase()`
The `toLowerCase()` method **converts all characters in a string to lowercase**.
- Standardize input, such as when comparing **user-provided** text or making **case-insensitive** checks.
```js
let shout = "I AM LEARNING JAVASCRIPT!";
let lowercaseShout = shout.toLowerCase();
console.log(lowercaseShout); // "i am learning javascript!"
```
## Trim Whitespace from a String
When working with strings in JavaScript, it's common to encounter **unwanted whitespace** at the beginning or end of a string. Whitespace can **interfere with operations** like **comparison**, **storage**, or **display**,
- Whitespace refers to **spaces**, **tabs**, or **line breaks** that occur in a string but are **not visible characters**.
### `trim()`
The `trim()` method is the most commonly used way to **remove whitespace** from both **the beginning** and **the end** of a string.
- Removes all the leading and trailing spaces.
```js
let message = " Hello! ";
console.log(message); // " Hello! "
let trimmedMessage = message.trim();
console.log(trimmedMessage); // "Hello!"
```
`Note`: Any whitespace **within the string** (_between words_) is left **untouched** by `trim()`.
### `trimStart()`
`trimStart()` removes whitespace from the **beginning** (_start_) of the string.
```js
let greeting = " Hello! ";
console.log(greeting); // " Hello! "
let trimmedStart = greeting.trimStart();
console.log(trimmedStart); // "Hello! "
```
### `trimEnd()`
`trimEnd()` removes whitespace from the **end of the string**.
```js
let greeting = " Hello! ";
console.log(greeting); // " Hello! "
let trimmedEnd = greeting.trimEnd();
console.log(trimmedEnd); // " Hello!"
```
## `replace()` method
The `replace()` method in JavaScript allows you to **find** a specified value (like a **word** or **character**) in a string and **replace** it with another value. The method **returns** a _new string_ with the replacement and leaves the original unchanged.
```js
string.replace(searchValue, newValue);
```
- Case-sensitive
- `searchValue` is the value you want to _search_ for in the string. It can be either a **string** or a regular expression (**regex**), which describes patterns in text.
- The `newValue` is the value that will **replace** the `searchValue`.
```js
let text = "I love JavaScript!";
console.log(text); // "I love JavaScript!"
let newText = text.replace("JavaScript", "Elixir");
console.log(newText); // "I love Elixir!"
```
`Note`: By default, the `replace()` method will only **replace the first occurrence** of the `searchValue`.
### `replaceAll()` method
it replaces all of the occourences of the `searchValue`.
## `repeat()` method
The `repeat()` method is a built-in function in JavaScript that allows you to **repeat a string a specified number of times**. it is used for **string duplication**.
```js
string.repeat(count);
```
- `string` is the string that you want to **repeat**, and `count` is the _number of times_ you want the string to be repeated.
```js
let word = "Hello!";
let repeatedWord = word.repeat(3);
console.log(repeatedWord); // "Hello!Hello!Hello!"
```
- The `count` parameter must be a **non-negative** number. if you pass a negative number, JavaScript will throw a `RangeError`.
```js
let word = "Test";
console.log(word.repeat(-1)); // Throws RangeError: Invalid count value
```
- The `count` must be a **finite** number. if you try to repeat a string an **_infinite_** number of times or use `Infinity` as the count, you will also get a `RangeError`.
```js
let word = "Test";
console.log(word.repeat(Infinity)); // Throws RangeError: Invalid count value
```
- in JavaScript, `Infinity` is a special value that represents an **infinite quantity**. it is used to denote numbers that are _larger than any finite number_.
- if the count is **not an integer** (such as a _decimal_ like `2.5`), the `repeat()` method will **round** it down to the nearest integer.
```js
let word = "Test";
console.log(word.repeat(2.5)); // "TestTest"
```
- if you pass `0` as the `count`, the `repeat()` method will return an empty string (`""`).
## `prompt()` method
One of the simplest ways to **get input from a user** through a small **pop-up dialog** box.
```js
prompt(message, default);
```
- Basic Example
```js
const btn = document.getElementById("prompt-btn");
const output = document.getElementById("output");
btn.addEventListener("click", () => {
const userName = prompt("What is your name?", "User");
output.textContent = "Hello, " + userName + "!";
});
```
- Returns the input as a **string**.
- `null` signifies that the user **did not** provide any **input**.
- `prompt()` method will **halt the execution** of the script **until the user interacts** with the _dialog box_.
`Note`: While `prompt()` is useful for **quick testing** or **small applications**, it's generally **avoided** in modern, complex web applications due to its **disruptive nature** and **inconsistent behavior** across different _browsers_.
## American Standard Code for Information Interchange (`ASCII`)
ASCII is **a system for encoding characters** such as letters, digits, and symbols into **numerical** values.
- Each **character** is mapped to a **specific** number.
- For example, `A` is represented by the number `65`, while `a` is represented by `97`.
- JavaScript strings use Unicode (`UTF-16`) internally, ASCII values match the first `128` Unicode characters.
- Uppercase and lowercase English letters (`A-Z`, `a-z`).
- Numbers (`0-9`).
- Common punctuation marks and symbols (`!`, `@`, `#`, and _so on_).
- Control characters (such as **newline** and **tab**).
in JavaScript, you can access the **numeric code of a character** using the `charCodeAt()` method. This method **returns the UTF-16 code** unit of the character at a specified **index**. For the first `128` _characters_, this value matches the ASCII code.
```js
let letter = "A";
console.log(letter.charCodeAt(0)); // 65
```
The `fromCharCode()` method allows you to do the **opposite**: convert a **UTF-16** code unit (which matches ASCII for basic characters) into its **corresponding character**.
```js
let char = String.fromCharCode(65);
console.log(char); // A
let char = String.fromCharCode(97);
console.log(char); // a
```
`Note`: These methods are particularly useful when you need to **manipulate or compare characters based on their numeric code values**.
## A Semicolon (`;`)
Semicolons are primarily used to **mark the end of a statement**. This helps the JavaScript engine understand **the separation of individual instructions**, which is crucial for correct execution and termination.
- Semicolons help **delineate statements**, and improve _code readability_ and \*reliability\*\*.
```js
let message = "Hello, World!"; // first statement ends here
let number = 42; // second statement starts here
```
Just as a period (`.`) marks the **end of a sentence** in _English_, a semicolon (`;`) signifies the **end of an executable line of code** in _JavaScript_.
- This allows the JavaScript engine to distinguish between separate commands.
Without the semicolon, the JavaScript engine \*might\*\* have trouble interpreting where one statement ends and another begins.
- Semicolons help **prevent ambiguities** in code execution and ensure that statements are _correctly terminated_.
`Note`: While JavaScript has Automatic Semicolon Insertion (**ASI**) that can add semicolons automatically, explicitly including them improves code clarity and helps prevent errors that may arise from _unexpected_ ASI behavior.
## Comments in JavaScript
Any line of code that is _commented_ out is **ignored** by the JavaScript engine. Comments are used to **explain code**, **make notes**, **documentation**, or **temporarily disable code**.
- They are there solely for the benefit of people **reading the code**, whether that's you or someone else.
- The comment provides important context for why "this" code _exists_.
### Single line (`//`)
```js
// I am a single line comment in JavaScript
```
### Multi-line (`/* */`)
```js
/*
I am a multiline comment.
This is helpful for longer explanations.
*/
```
While comments are **useful** in programming, it is important to **avoid over-commenting**. You don't need to comment on every single line of code, especially if the code is straightforward and self-explanatory.
`Note`: The goal is to **enhance readability**, **do not clutter** the code with _unnecessary_ explanations.
## Data Types in JavaScript
- `Number`: A number represents both **integers** and **floating-point** values.
- Examples of integers include 7, 19, and 90.
- **Floating point**: A floating point number is a number with a **decimal** point.
- Examples include 3.14, 0.5, and 0.0001.
- in JavaScript, there isn't a _dedicated_ Float data type. instead, all numbers, including both **integers** and **floating-point** numbers, are _represented_ by a single `Number` type.
- `String`: A string is a **sequence of characters**, or **text**, enclosed in **quotes**.
- `"I like coding"` and `'JavaScript is fun'` are examples of strings.
- `Boolean`: A boolean represents one of two possible values: `true` or `false`.
- To represent a condition, such as `isLoggedIn = true`.
- `Undefined`: An undefined value is a variable that has been declared but **not assigned** a value.
- `Null`: A value is an `empty` value, or a variable that has `intentionally` been assigned a value of null.
- `Object`: An object is a collection of **key-value** pairs. The key is the property _name_, and the value is the property _value_.
- Here, the `pet` object has three properties or **keys**: `name`, `age`, and `type`. The values are `Fluffy`, `3`, and `dog`, respectively.
```js
let pet = {
name: "Fluffy",
age: 3,
type: "dog",
};
```
- `Symbol`: The Symbol data type is a **unique** and **immutable** value that may be used as an **identifier** for object properties.
- in this example below, two symbols are created with the **same description**, but they are **not equal**.
```js
const crypticKey1 = Symbol("saltNpepper");
const crypticKey2 = Symbol("saltNpepper");
console.log(crypticKey1 === crypticKey2); // false
```
- `BigInt`: When the number is **too large** for the `Number` data type, you can use the `BigInt` data type to represent **integers of arbitrary length**.
- By adding an `n` to the end of the number, you can create a BigInt.
```js
const veryBigNumber = 1234567890123456789012345678901234567890n;
```
## `typeof` Operator
The typeof operator is used to **check the data type of a variable**. it returns a _string_ indicating the _type_ of the variable.
```js
let age = 25;
console.log(typeof age); // "number"
let isLoggedIn = true;
console.log(typeof isLoggedIn); // "boolean"
```
- However, there's a well-known "_quirk_"/_bug_ in JavaScript when it comes to `null`. The `typeof` operator returns `"object"` for `null` values.
```js
let user = null;
console.log(typeof user); // "object"
```
When the language was first implemented, values like `null` were represented as a **"special" type of object**, leading to this _unexpected_ result.
_Unfortunately_, this has become **a part of the language**, and while it's confusing, it's something **you'll need to be aware of**.(
## Number
The `Number` data type represents a **numeric** value. JavaScript uses one unified `Number` type to account for numbers.
```js
const wholeNumber = 50;
const decimalNumber = 4.5;
const negativeNumber = -7;
console.log(typeof wholeNumber); // number
console.log(typeof decimalNumber); // number
console.log(typeof negativeNumber); // number
```
- JavaScript's `Number` type includes various kinds of numeric values, ranging from simple **integers** and **floating-point** numbers to special cases like `Infinity` and `NaN`.
- JavaScript can represent numbers that are beyond the maximum limit with `Infinity`. it comes up when **dividing a number by zero** or **exceeding the upper boundary** of the `Number` type.
```js
const infiniteNumber = 1 / 0;
console.log(infiniteNumber); // Infinity
console.log(typeof infiniteNumber); // number
```
- in JavaScript, some mathematical operations **don't result in a valid number**, i.e., why `NaN`, which stands for "Not a Number".
```js
const notANumber = "hello world" / 2;
console.log(notANumber); // NaN
console.log(typeof notANumber); // number
```
`Note`: Apart from the **standard decimal system** (`base 10`), JavaScript also **supports** numbers in different bases such as _binary_, _octal_, and _hexadecimal_. **Binary** is a `base-2` system that uses only digits `1` and `0`. **Octal** is a `base-8` system that uses only digits `0 to 7`. **Hexadecimal** is a `base-16` system that uses digits `0 to 9` and letters `a to f`, like you see in CSS _hex_ colors.
## Arithmetic Operators
JavaScript provides tools to perform basic _arithmetic operations_ on numbers, such as **addition** (`+`), **subtraction** (`-`), **multiplication** (`*`), and **division** (`/`).
- JavaScript also includes operators for more _complex_ arithmetic operations, such as **remainder** (`%`) and **exponentiation** (`**`).
`Note`: When you mix different operators in a single expression, the JavaScript engine follows a system called operator precedence to determine the order of operations. **Operator precedence determines the order in which operations are executed** in expressions.
## Calculations with `Numbers` and `Strings`
JavaScript is a language where things sometimes work in surprising, or even **weird**, ways. One such surprise occurs when you **mix numbers and strings** in calculations.
- **Type coercion** is when a value from one data type is converted into another.
### Number + String = String concatenation
in JavaScript, the `+` operator does **double duty**. It handles both **addition** and **string concatenation**.
```js
const result = 5 + "10";
console.log(result); // 510
console.log(typeof result); // string
```
- When you try to perform other arithmetic operations like **subtraction**, **multiplication**, or **division** with **a string and number**. In these cases, JavaScript tries to convert the string into a **number** before doing the math – another type coercion!
```js
const subtractionResult = "10" - 5;
console.log(subtractionResult); // 5
console.log(typeof subtractionResult); // number
const multiplicationResult = "10" * 2;
console.log(multiplicationResult); // 20
console.log(typeof multiplicationResult); // number
const divisionResult = "20" / 2;
console.log(divisionResult); // 10
console.log(typeof divisionResult); // number
```
- But what if the **string isn't a number**? (`NaN`)
```js
const subtractionResult = "abc" - 5;
console.log(subtractionResult); // NaN
console.log(typeof subtractionResult); // number
const multiplicationResult = "abc" * 2;
console.log(multiplicationResult); // NaN
console.log(typeof multiplicationResult); // number
const divisionResult = "abc" / 2;
console.log(divisionResult); // NaN
console.log(typeof divisionResult); // number
```
- in the examples above, the string `'abc'` does not represent a valid numeric value, so JavaScript cannot convert it into a **meaningful number**. When such **conversion fails**, JavaScript returns `NaN`, which stands for "_Not a Number_".
- JavaScript treats **booleans as numbers** in mathematical operations: `true` becomes `1`, and `false` becomes `0`.
```js
const result1 = true + 1;
console.log(result1); // 2
console.log(typeof result1); // number
const result2 = false + 1;
console.log(result2); // 1
console.log(typeof result2); // number
const result3 = "Hello" + true;
console.log(result3); // "Hellotrue"
console.log(typeof result3); // string
```
- JavaScript treats `null` as `0` and `undefined` as `NaN` in mathematical operations.
```js
const result1 = null + 5;
console.log(result1); // 5
console.log(typeof result1); // number
const result2 = undefined + 5;
console.log(result2); // NaN
console.log(typeof result2); // number
```
`Note`: JavaScript often performs **type coercion**, _automatically_ converting data types such as numbers, strings, and booleans in sometimes **unexpected ways**.
## Operator Precedence
Operator precedence determines **the order in which operations are evaluated** in an expression. Think of operator precedence like in **mathematics**, where division and multiplication happen before addition and subtraction.
- Operators with **higher** precedence are evaluated before those with **lower** precedence.
```js
const result = 2 + 3 * 4;
console.log(result); // 14
const result = 2 + 6 / 3;
console.log(result); // 4
```
- Similar to mathematics, you can use parentheses `()` around certain parts of your expression to run _first_, **regardless of precedence** rules.
```js
const result = (2 + 3) * 4;
console.log(result); // 20
```
- **Associativity** is what tells JavaScript whether to evaluate operators from **left to right** or **right to left**.
- For most operators like **addition** and **multiplication**, associativity is **_left to right_**.
```js
const result = 10 - 2 + 3;
console.log(result); // 11
```
- Some operators, like assignment (`=`), are **right-to-left** associative. This means the right side of the expression gets evaluated first.
```js
let a, b;
a = b = 5;
console.log(a); // 5
console.log(b); // 5
console.log(a + b); // 10
```
- The exponent operator (`**`) is also **right-to-left** associative.
```js
const result = 2 ** (3 ** 2);
console.log(result); // 512
```
## increment and Decrement Operators
The increment and decrement operators are represented by `++` and `--`, respectively. They both allow you to adjust the value of a variable by `1`.
- instead of writing something like `x = x + 1` or `x = x - 1`, you can simply use `x++` to add `1`, or `x--` to subtract `1`.
- it's faster, cleaner, and easier to read.
- **Prefix** & **Postfix**
- Prefix (`++x`) **increases** the value of the variable **first**, then returns a new value.
```js
let x = 5;
console.log(++x); // 6
console.log(x); // 6
```
- Postfix (`x++`) **returns** the current value of the variable **first**, then increases it.
```js
let y = 5;
console.log(y++); // 5
console.log(y); // 6
```
`Note`: So, if you **need the updated value right away**, use **prefix**. If you **want the current value first** and you don’t care about the **increment** until **later**, go with **postfix**.
## Compound Assignment Operators
Compound assignment operators provide a concise **shorthand** for an operation on a variable followed by storing the result in that **same variable**. They combine the **operation and assignment** into a shorter form like `x += y`, which is equivalent to writing `x = x + y` but **without repeating the variable name**.
- The **addition assignment operator** (`+=`) takes the current value of the variable, adds the specified number to it, and then assigns the result back to the variable.
```js
let total = 10;
total += 5;
console.log(total); // 15
```
- There's a **subtraction** assignment operator (`-=`)
- The **multiplication** assignment operator (`*=`)
- Lastly, there's a **division** assignment operator (`/=`)
- There's a compound assignment operator for every operator in JavaScript. So, apart from the four already mentioned, we also have...
- **Remainder assignment** operator (`%=`), which divides a variable by the specified number and assigns the remainder to the variable.
- **Exponent assignment** operator (`**=`), which raises a variable to the power of the specified number and reassigns the result to the variable.
- **Bitwise AND assignment** operator (`&=`), which performs a bitwise AND operation with the specified number and reassigns the result to the variable.
- **Bitwise OR assignment** operator (`|=`), which performs a bitwise OR operation with the specified number and reassigns the result to the variable.
## Booleans, Equality and inequality Operators
Booleans are a data type with only `true` and `false` values. They're useful because they allow you to do something based on some **conditions**.
- To compare two values, you can use either the equality (`==`) or strict equality (`===`) operator. The result of the comparison will be a boolean of either `true` or `false`.
```js
// equality: performs type coercion
console.log(5 == "5"); // true
// strict equality
console.log(5 === "5"); // false
// inequality
console.log(5 != "5"); // false
// strict inequality
console.log(5 !== "5"); // true
```
- Type coercion converts the **string** value to a **number** and then _compares_ the values.
`Note`: it is considered best practice to **use strict** inequality and equality operators whenever possible, as _they do not perform type coercion_. it checks both **value** and **type**, providing more _predictable_ results.
## Comparison Operators
Comparison operators allow you to **compare two values** and return a `true` or `false` result. You can then use the result to make a decision or control the flow of your program.
- The greater than operator (`>`), checks if the value on the _left_ is **greater** than the one on the _right_.
```js
let a = 6;
let b = 9;
console.log(a > b); // false
console.log(b > a); // true
```
- The greater than or equal operator (`>=`), checks if the value on the _left_ is **either greater than or equal** to the one on the _right_.
```js
let a = 6;
let b = 9;
let c = 6;
console.log(a >= b); // false
console.log(b >= a); // true
console.log(a >= c); // true
```
- The lesser than operator (`<`) checks if the value on the _left_ is **smaller** than the one on the _right_.
```js
let a = 6;
let b = 9;
console.log(a < b); // true
console.log(b < a); // false
```
- The less than or equal operator (`<=`) checks if the value on the _left_ is **smaller than or equal** to the one on the _right_.
```js
let a = 6;
let b = 9;
let c = 6;
console.log(a <= b); // true
console.log(b <= a); // false
console.log(a <= c); // true
```
## `null` vs. `undefined`
in JavaScript, `null` and `undefined` are two distinct data types that **represent the absence of a value**, but they **behave differently** in comparisons.
- A variable is `undefined` when it has been **declared but hasn't been assigned a value**. it is the **default value** of **uninitialized variables** and **function parameters** that weren't provided an *argument*.
- The `null` type is an assignment value that **represents a deliberate non-value**. it is often used to indicate that a variable **intentionally has no value**.
### w/ Equality Operator (`==`)
When comparing `null` and `undefined` using the **equality operator**, JavaScript performs **type coercion**. This means it tries to convert the operands to the same type before making the comparison. In this case, `null` and `undefined` are **considered equal**.
```js
console.log(null == undefined); // true
```
The comparisons below return `false` because `null` and `undefined` are **only equal to each other (and themselves)** when using the **equality operator**.
```js
console.log(null == 0); // false
console.log(null == ''); // false
console.log(undefined == 0); // false
console.log(undefined == ''); // false
```
Tricky AF.
```js
console.log(null > 0); // false
console.log(null == 0); // false
console.log(null >= 0); // true
```
`undefined`, on the other hand, **always converts to `NaN`** in numeric contexts, which makes **all numeric comparisons with `undefined` return `false`**.
```js
console.log(undefined > 0); // false
console.log(undefined < 0); // false
console.log(undefined == 0); // false
```
### w/ Strict Equality Operator (`===`)
However, when using the **strict equality operator**, which checks both value and type **without performing type coercion**, `null` and `undefined` are **not equal**.
```js
console.log(null === undefined); // false
```
`Note`: Given these nuances, it is generally recommended to **use the strict equality operator when comparing values**, especially when dealing with `null` and `undefined`. This approach **helps avoid unexpected type coercion** and makes your code's behavior more *predictable*.
## Unary Operators
Unary operators act on a **single operand to perform operations** like **type conversion**, **value manipulation**, or checking certain **conditions**.
- The **unary plus** operator **converts its operand into a number**. If the operand is already a number, it remains unchanged.
- Unary plus is handy when you want to **make sure** you're working with **a numeric value**.
```js
const str = "42";
const strToNum = +str;
console.log(strToNum); // 42
console.log(typeof str); // string
console.log(typeof strToNum); // number
```
- The **unary negation operator** works the same as plus, except it **negates the value** of the operand. in other words, it **flips the sign** from `+` to a `-`.
```js
const str = "42";
const strToNegativeNum = -str;
console.log(strToNegativeNum); // -42
console.log(typeof str); // string
console.log(typeof strToNegativeNum); // number
```
- The **logical NOT** operator, represented by an exclamation mark (`!`), is another unary operator. it **flips the boolean value** of its operand. So, if the operand is `true`, it becomes `false`, and if it's `false`, it becomes `true`.
```js
let isOnline = true;
console.log(!isOnline); // false
let isOffline = false;
console.log(!isOffline); // true
```
- The `void` keyword is a unary operator that **evaluates an expression** and **returns** `undefined`.
```js
const result = void (2 + 2);
console.log(result); // undefined
```
- `void` is also commonly used in _hyperlinks_ to **prevent navigation**.
```js
Click Me
```
- The `typeof` operator **returns the type** of its operand as a **string**.
```js
const value = "Hello world";
console.log(typeof value); // string
```
- The **bitwise NOT** operator (`~`) **inverts the binary representation of a number**. Computers store numbers in binary format (1s and 0s). The `~` operator **flips every bit**, meaning it changes all **1s to 0s** and all **0s to 1s**.
```js
const num = 5; // The binary for 5 is 00000101
console.log(~num); // -6
```
- in this example, `5` became `-6` because by applying the `~` operator to `5`, you get `- (5 + 1)`, which equals `-6` due to two's complement representation. Two's complement is a way computers represent negative numbers in binary. You probably won't use the bitwise NOT often unless you're working with low-level programming tasks like **manipulating bits directly**.
## Bitwise Operators
Bitwise operators in JavaScript are special operators that **work on the binary representation of numbers**.
- A **bit** is the most basic unit of information.
- it can have only two values: `0` or `1`.
- **Binary** is a **number system** that uses only `0` and `1` to represent all numbers.
- in binary, each digit represents a **power of** `2`, _starting_ from the **rightmost** digit and _increasing_ as we move **left**.
```
- 10 in binary is 1010
1 0 1 0
1*(2**3) = 8 0*(2**2) = 0 1*(2**1) = 2 0*(2**0) = 0 => 8+0+2+0 = 10
```
- **Bitwise operators** perform **operations on the binary representation** of numbers.
- The bitwise **AND** (`&`) operator **returns** a `1` in each bit position for which the corresponding bits of both operands are `1`.
```js
let a = 5; // Binary: 101
let b = 3; // Binary: 011
console.log(a & b); // 1 (Binary: 001)
```
- The bitwise **OR** (`|`) operator **returns** a `1` in each bit position for which the corresponding bits of either or both operands are `1`.
```js
let a = 5; // Binary: 101
let b = 3; // Binary: 011
console.log(a | b); // 7 (Binary: 111)
```
- The bitwise **XOR** (`^`) operator **returns** a `1` in each bit position for which the corresponding bits of either, but not both, operands are `1`.
```js
let a = 5; // Binary: 101
let b = 3; // Binary: 011
console.log(a ^ b); // 6 (Binary: 110)
```
- The bitwise **NOT** (`~`) operator **inverts** all the **bits** of its operand.
```js
let a = 5; // Binary: 101
console.log(~a); // -6
```
- This might seem surprising, but it's because of how negative numbers are represented in binary using two's complement.
- The left shift (`<<`) operator **shifts** all bits to the **left** by a specified number of positions.
```js
let a = 5; // Binary: 101
console.log(a << 1); // 10 (Binary: 1010)
```
- Here, all bits are shifted one position to the left, effectively **multiplying** the number by `2`.
- The right shift (`>>`) operator **shifts** all bits to the **right**.
```js
let a = 5; // Binary: 101
console.log(a >> 1); // 2 (Binary: 10)
```
- Here, all bits are shifted one position to the right, effectively **dividing** the number by `2` and rounding down.
`Note`: Bitwise operators are often used in **low-level programming** and **cryptography**. While they may not be as commonly used in everyday JavaScript programming, understanding them can be beneficial for certain **specialized tasks** and can deepen your understanding of **how computers work at a fundamental level**.
## Conditional Statements
Conditional statements let you **make decisions** in your JavaScript code. They allow your program to flow in a particular way **based on certain conditions**.
- An `if` statement takes a condition and runs a block of code if that condition is **truthy**. Truthy values are any values that result in `true` when evaluated in a Boolean context.
- non-empty strings
- **any other number** than `0` and `-0`
- arrays
- objects
- the boolean `true`
- Falsy values are values that evaluate to `false` in a boolean context.
- boolean `false`
- `0` (zero)
- `""` (empty string)
- `null`
- `undefined`
- `NaN` (Not a Number)
```js
if (null) {
console.log("This will not run.");
}
if ("freeCodeCamp") {
console.log("This will run.");
}
```
- When a condition is `false`, then you can use an `else` clause:
```js
const age = 15;
if (age >= 18) {
console.log("You're eligible to vote");
} else {
console.log("You're not eligible to vote"); // You're not eligible to vote
}
```
- When you want to check **multiple conditions**, you can use an `else if` block.
```js
const score = 87;
if (score >= 90) {
console.log("You got an A");
} else if (score >= 80) {
console.log("You got a B"); // You got a B
} else if (score >= 70) {
console.log("You got a C");
} else {
console.log("You failed! You need to study more!");
}
```
## Ternary Operator (`?:`)
The **ternary operator** is a compact way to write **simple if/else statements**.
```js
condition ? expressionIfTrue : expressionIfFalse;
```
```js
const temperature = 30;
const weather = temperature > 25 ? "sunny" : "cool";
console.log(`It's a ${weather} day!`);
```
## Switch Case
A `switch` statement **evaluates an expression** and matches its value against a series of `case` clauses. When a match is found, the code block associated with that `case` is executed.
```js
switch (expression) {
case value1:
// code to be executed if expression === value1
break;
case value2:
// code to be executed if expression === value2
break;
default:
// code to be executed if expression doesn't match any case
}
```
- The `break` statement at the end of each case is **crucial**. it tells the program to **exit the switch block once a matching case has been executed**. Without it, the program would continue executing subsequent cases, a behavior known as "**fall-through**".
### When to Use
`switch` statements are typically used when you're **comparing a single variable against multiple possible values**. They're especially useful when you have **many potential conditions** to check against a **single variable**.
```js
let dayOfWeek = 3;
switch (dayOfWeek) {
case 1:
console.log("It's Monday! Time to start the week strong.");
break;
case 2:
console.log("It's Tuesday! Keep the momentum going.");
break;
case 3:
console.log("It's Wednesday! We're halfway there.");
break;
case 4:
console.log("It's Thursday! Almost the weekend.");
break;
case 5:
console.log("It's Friday! The weekend is near.");
break;
case 6:
console.log("It's Saturday! Enjoy your weekend.");
break;
case 7:
console.log("It's Sunday! Rest and recharge.");
break;
default:
console.log("Invalid day! Please enter a number between 1 and 7.");
}
```
- `switch` statements can be more **readable** and **concise** when dealing with **many possible values** for a **single variable**.
- `switch` statements in use **strict comparison** (`===`) by default, which means they **don't perform type coercion**. This can be an advantage in terms of *predictability* and avoiding subtle *bugs*.
### When Not to Use
`if/else if` statements are **more flexible**. They can evaluate complex conditions and different variables in each clause. This makes them suitable for a wider range of scenarios. Especially with **multiple variables**.
```js
let creditScore = 720;
let annualIncome = 60000;
let loanAmount = 200000;
let eligibilityStatus;
if (creditScore >= 750 && annualIncome >= 80000) {
eligibilityStatus = "Eligible for premium loan rates.";
} else if (creditScore >= 700 && annualIncome >= 50000) {
eligibilityStatus = "Eligible for standard loan rates.";
} else if (creditScore >= 650 && annualIncome >= 40000) {
eligibilityStatus = "Eligible for subprime loan rates.";
} else if (creditScore < 650) {
eligibilityStatus = "Not eligible due to low credit score.";
} else {
eligibilityStatus = "Not eligible due to insufficient income.";
}
console.log(eligibilityStatus);
```
`Note`: `switch` statements **excel at handling multiple possible values for a "single variable"**, while `if/else if` chains offer **more flexibility for complex conditions**.
## Binary Logical Operators
Binary logical operators help you **evaluate** two expressions and return a result based on their **truthiness**.
### Logical AND (`&&`)
it checks if **both** operands are **true** and returns a result.
- if **both** operands are **truthy**, it _returns_ the **second value**, that is, the one on the **right**:
```js
const result = true && "hello";
console.log(result); // hello
```
- if **either** operand is **falsy**, it _returns_ the **falsy value**:
```js
const result = 0 && 3;
console.log(result); // 0
```
- if **both** operands are **falsy**, it _returns_ the first **falsy value**:
```js
const result = false && 0;
console.log(result); // false
```
- The **logical AND** operator is useful when you want to **check multiple conditions** and ensure that all are **true** before proceeding.
```js
if (2 < 3 && 3 < 4) {
console.log("The if block runs");
} else {
console.log("The else block runs");
}
```
### Logical OR (`||`)
This operator checks if at least **one** of the operands is **truthy**. if the first operand is **truthy**, it **returns** that value:
```js
const result = "This is truthy" || false;
console.log(result); // This is truthy
```
- if the **first** operand is **falsy** but the **second** is **truthy**, the **second value will be logged** to the console:
```js
const result = 0 || "This is truthy";
console.log(result); // This is truthy
```
- An example:
```js
let userInput;
if (userInput || 'Guest') {
console.log('A user is present');
} else {
console.log('No user detected');
}
```
### Nullish Coalescing (`??`)
it helps in scenarios where you want to **return** a value **only if** the **first value** is `null` or `undefined`.
```js
const result = null ?? 'default';
console.log(result); // default
```
- The nullish coalescing operator is incredibly useful in situations where **`null` or `undefined` are the only values that should trigger a fallback** or default value.
```js
const userSettings = {
theme: null,
volume: 0,
notifications: false,
};
let theme = userSettings.theme ?? 'light';
console.log(theme); // light
```
## The Math Object
While basic arithmetic operators can handle simple calculations, JavaScript offers a *built-in* Math object to tackle more **complex math** challenges.
### `Math.random()`
This method **generates a random floating-point number** between `0` (*inclusive*) and `1` (*exclusive*).
- This means the possible output can be `0`, but it will never actually reach `1`.
```js
const randomNum = Math.random();
console.log(randomNum);
// any number between 0 and 1 – 0 inclusive and 1 exclusive
```
### `Math.min()` & `Math.max()`
They both take **a set of numbers** and return the **minimum** and **maximum** value, *respectively*.
```js
const smallest = Math.min(1, 5, 3, 9);
console.log(smallest); // 1
const largest = Math.max(1, 5, 3, 9);
console.log(largest); // 9
```
### `Math.ceil()` & `Math.floor()`
if you wanted to **round numbers up or down** to the nearest whole integer, you could use the `Math.ceil()` and `Math.floor()` methods.
```js
console.log(Math.ceil(4.3)); // 5
console.log(Math.floor(4.7)); // 4
```
### `Math.round()`
Math.round() is the **hybrid** of `Math.ceil()` and `Math.floor()`. it **rounds a number** to its nearest integer, **taking the decimal point into account**:
```js
console.log(Math.round(2.3)); // 2
console.log(Math.round(4.5)); // 5
console.log(Math.round(4.8)); // 5
```
- if the decimal point is **less than 5**, the number is **rounded down**.
- And if the decimal point is **5 or greater**, the number is **rounded up**.
### Random Number Generator
```js
Math.floor(Math.random() * (maximum - minimum) + minimum);
```
Generating a random number between two whole numbers.
```js
const max = 10;
const min = 5;
const randomNum = Math.floor(Math.random() * (max - min + 1)) + min;
console.log(randomNum);
// Generating a random number between 20 and 1
const randomNumBtw1And20 = Math.floor(Math.random() * 20) + 1;
console.log(randomNumBtw1And20);
```
### `Math.trunc()`
it **removes the decimal part** of a number, returning only the integer portion, **without rounding**.
```js
console.log(Math.trunc(2.9)); // 2
console.log(Math.trunc(9.1)); // 9
```
### `Math.sqrt()` & `Math.cbrt()`
If you need to get the **square root** or **cube root** of a number, you can use the Math.sqrt() and Math.cbrt() methods, respectively.
```js
console.log(Math.sqrt(81)); // 9
console.log(Math.cbrt(27)); // 3
```
### `Math.abs()`
if you need to get the **absolute value of a number**, you can use the Math.abs() method. it returns the absolute value of a number, **turning negatives into positives**.
```js
console.log(Math.abs(-5)); // 5
console.log(Math.abs(5)); // 5
```
### `Math.pow()`
it takes two numbers and **raises the second as the power to the first**.
```js
console.log(Math.pow(2, 3)); // 8
console.log(Math.pow(8, 2)); // 64
```
## Not a Number (`NaN`)
It's a special value that represents an **unrepresentable** or **undefined** numerical result. `NaN` is a property of the **global object**, and it's also considered a type of **number** in JavaScript, which might seem *counterintuitive* at first.
- `NaN` is typically the result of operations that should return a number but **cannot produce a meaningful numerical value**.
```js
let result = 0 / 0;
console.log(result); // NaN
```
- Dividing zero by zero is mathematically **undefined**, so JavaScript returns `NaN`.
- One peculiar property of `NaN` is that **it is not equal to anything**, including *itself*.
```js
console.log(NaN === NaN); // false
```
### `isNaN()`
The `isNaN()` function property is used **to determine whether a value is `NaN` or not**. it perform **type coercion** by default which can lead to *unexpected* results.
```js
console.log(isNaN(NaN)); // true
console.log(isNaN(undefined)); // true
console.log(isNaN({})); // true
console.log(isNaN(true)); // false
console.log(isNaN(null)); // false
console.log(isNaN(37)); // false
console.log(isNaN("37")); // false: "37" is converted to 37
console.log(isNaN("37.37")); // false: "37.37" is converted to 37.37
console.log(isNaN("")); // false: empty string is converted to 0
console.log(isNaN(" ")); // false: string with a space is converted to 0
console.log(isNaN("blabla")); // true: "blabla" is not a number
```
### `Number.isNaN()`
it **does not perform type coercion** before testing. it only returns `true` if the value is exactly `NaN`.
- introduced in **ES6**
```js
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(Number.NaN)); // true
console.log(Number.isNaN(0 / 0)); // true
console.log(Number.isNaN("NaN")); // false
console.log(Number.isNaN(undefined)); // false
console.log(Number.isNaN({})); // false
console.log(Number.isNaN("blabla")); // false
```
- `Number.isNaN()` provides a more reliable way to check for `NaN` values, especially in cases where **type coercion might lead to unexpected results** with the global `isNaN()` function.
### `NaN` Based Error Handling
when dealing with numerical operations or user inputs that should be numbers, it's often necessary to **check for `NaN`** to handle **errors** or **unexpected inputs** gracefully.
```js
let a = 0;
let b = 0;
let result = a / b;
if (Number.isNaN(result)) {
result = "Error: Division resulted in NaN";
}
console.log(result); // "Error: Division resulted in NaN"
```
## `parseFloat()` & `parseInt()` Methods
These are two essential methods in JavaScript for **converting strings to numbers**. These methods are particularly useful when dealing with **user input** or **processing data** that comes in *string* format but needs to be treated as *numerical* values.
### `parseFloat()`
This method parses a **string** argument and returns a **floating-point** number. it is designed to *extract* a number from the **beginning** of a string.
```js
console.log(parseFloat("3.14")); // 3.14
console.log(parseFloat("3.14 abc")); // 3.14
console.log(parseFloat("3.14.5")); // 3.14
console.log(parseFloat("abc 3.14")); // NaN
```
### `parseInt()`
This method parses a **string** argument and returns an **integer**. it also starts from the **beginning** of the string, but it **stops at the first non-digit character**.
```js
console.log(parseInt("42")); // 42
console.log(parseInt("42px")); // 42
console.log(parseInt("3.14")); // 3
console.log(parseInt("abc123")); // NaN
```
- They both **ignore leading whitespace**.
```js
console.log(parseFloat(" 3.14")); // 3.14
console.log(parseInt(" 42")); // 42
```
- They both handle **plus and minus signs** at the beginning of the string.
```js
console.log(parseFloat("+3.14")); // 3.14
console.log(parseInt("-42")); // -42
```
`Note`: They don't handle all number formats, such as **scientific notation**, directly. For more complex parsing needs, you might need to use additional techniques or libraries.
## `toFixed()`
This method is a built-in JavaScript function that **formats a number using fixed-point notation**. It's particularly useful when you need to control **the number of decimal places in a number**, especially for displaying **currency** values or when working with **precise measurements**.
- For precise calculations.
- it takes **one optional argument**, which is **the number of digits** to appear after the decimal point. it **returns** a **"string"** representation of the number with the specified number of decimal places.
```js
let num = 3.14159;
console.log(num.toFixed(2)); // "3.14"
```
- The `.toFixed()` method **rounds the number to the nearest value** that can be represented with the specified number of decimal places.
```js
console.log((3.14159).toFixed(3)); // "3.142"
console.log((3.14449).toFixed(3)); // "3.144"
console.log((3.14550).toFixed(3)); // "3.146"
```
- if you call `.toFixed()` **without arguments**, it defaults to `0` decimal places.
```js
let num = 3.14159;
console.log(num.toFixed()); // "3"
```
- The `.toFixed()` method can be particularly useful when working with **financial calculations** or displaying **prices**.
```js
let price = 19.99;
let taxRate = 0.08;
let total = price + (price * taxRate);
console.log("Total: $" + total.toFixed(2)); // "Total: $21.59"
```
## Functions
Functions allow you to write **reusable** and **organized** code. They can take inputs (**parameters**), perform *actions*, and `return` **outputs**. Functions makes your code more **modular**, **easier to maintain**, and more **efficient**.
```js
function greet() {
console.log("Hello, Jessica!");
}
greet(); // "Hello, Jessica!"
```
- **Parameters** act as **placeholders** for the values that will be passed to the function when it is called.
```js
function greet(name) {
console.log("Hello, " + name + "!");
}
greet("Alice"); // Hello, Alice!
greet("Nick"); // Hello, Nick!
```
- When a function finishes execution, it will always **return a value**. By default, the return value will be `undefined`.
```js
function doSomething() {
console.log("Doing something...");
}
let result = doSomething();
console.log(result); // undefined
```
- if you need your function to return a specific value, then you will need to use the `return` statement.
```js
function calculateSum(num1, num2) {
return num1 + num2;
}
console.log(calculateSum(3, 4)); // 7
```
### Default Parameters
Functions support default parameters, allowing you to **set default values for parameters**.
```js
function greetings(name = "Guest") {
console.log("Hello, " + name + "!");
}
greetings(); // Hello, Guest!
greetings("Anna"); // Hello, Anna!
```
## Anonymous Function
An anonymous function is a function **without a name** that can be **assigned to a variable**.
```js
const sum = function (num1, num2) {
return num1 + num2;
};
console.log(sum(3, 4)); // 7
```
## Arrow Function Expression
```js
const greetings = (name) => {
console.log("Hello, " + name + "!");
};
```
- if your parameter list only has **one** parameter in it, then you can **remove** the parentheses.
```js
const greetings = name => {
console.log("Hello, " + name + "!");
};
```
- But if your arrow function has **no** parameters, then you **must use the parentheses**.
```js
const greetings = () => {
console.log("Hello");
};
```
- And if your function body only contains only a **single line of code**, you can **remove** the curly braces.
```js
const greetings = name => console.log("Hello, " + name + "!");
```
- if you're using `return` inside the function, you **must use the curly braces**.
```js
const calculateArea = (width, height) => {
return width * height;
};
console.log(calculateArea(5, 3)); // 15
```
- Even if you **remove** that `return` statement, the function will still **implicitly `return`** the calculation.
```js
const calculateArea = (width, height) => width * height;
```
## Scope
Scope in programming refers to the **visibility and accessibility of variables** in different parts of your code. it determines where variables can be accessed or modified.
### Global Scope
it is the **outermost** scope in a JavaScript program. Variables declared in the global scope are **accessible from anywhere** in your code, including within functions and blocks. These variables are often called **global variables**.
```js
let globalVar = "I'm a global variable";
function printGlobalVar() {
console.log(globalVar);
}
printGlobalVar(); // "I'm a global variable"
```
- While global variables should be used **sparingly**, as they can lead to **naming conflicts** and make your code **harder to maintain**.
### Local Scope
it refers to variables that are **only accessible within a function**.
```js
function greet() {
let message = "Hello, local scope!";
console.log(message);
}
greet(); // "Hello, local scope!"
// console.log(message); // This will throw an error
```
- Local variables help to keep different parts of your code **isolated**, which is especially useful in larger programs.
### Block Scope
A block is any code section **within** curly braces, `{}`, such as in `if` statements, `for` loops, or `while` loops.
```js
if (true) {
let blockVar = "I'm in a block";
console.log(blockVar); // "I'm in a block"
}
console.log(blockVar); // This will throw an error
```
- Block scope is a concept introduced with the **let** and **const** keywords in **ES6**.
- Block scoping provides even **finer control** over variable accessibility, helping to prevent errors and make your code **more predictable**.
##