{"id":23155794,"url":"https://github.com/skywalkersam/js-101","last_synced_at":"2026-05-05T12:32:28.995Z","repository":{"id":266844381,"uuid":"899415892","full_name":"skywalkerSam/JS-101","owner":"skywalkerSam","description":"JavaScript 101","archived":false,"fork":false,"pushed_at":"2026-05-01T14:20:40.000Z","size":9670,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-01T15:32:07.337Z","etag":null,"topics":["freecodecamp","javascript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skywalkerSam.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-06T08:13:34.000Z","updated_at":"2026-04-20T08:34:02.000Z","dependencies_parsed_at":"2025-03-21T13:51:15.586Z","dependency_job_id":null,"html_url":"https://github.com/skywalkerSam/JS-101","commit_stats":null,"previous_names":["skywalkersam/js-101"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/skywalkerSam/JS-101","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skywalkerSam%2FJS-101","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skywalkerSam%2FJS-101/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skywalkerSam%2FJS-101/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skywalkerSam%2FJS-101/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skywalkerSam","download_url":"https://codeload.github.com/skywalkerSam/JS-101/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skywalkerSam%2FJS-101/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32649548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-05T11:29:49.557Z","status":"ssl_error","status_checked_at":"2026-05-05T11:29:48.587Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["freecodecamp","javascript"],"created_at":"2024-12-17T21:11:37.723Z","updated_at":"2026-05-05T12:32:28.967Z","avatar_url":"https://github.com/skywalkerSam.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [introduction to JavaScript](https://www.freecodecamp.org/learn/javascript-v9/)\n\nw/ freeCodeCamp.org\n\n- **immutability** means that once something is _created_, it **cannot be changed**.\n\n- A `function()` is a reusable block of code that performs a specific task and can be called with various inputs.\n\n- A `method` is a _type of function_ that is associated with an `object`, meaning it operates on the data contained _within that object_.\n\n- 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**.\n\n- A **compiler** translates high-level programming language code into **machine-readable** code, which creates an **executable** file.\n\n\u0026nbsp;\n\n## JavaScript is a Dynamically Typed Language\n\nit 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**.\n\n```js\nlet error = 404; // JavaScript treats error as a number\nerror = \"Not Found\"; // JavaScript now treats error as a string\n```\n\n`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\\*\n\n### Statically Typed Languages\n\nin **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_.\n\n- Other languages, like `C#`, that are **not dynamically typed** would result in an error:\n\n  ```c\n  int error = 404; // value must always be an integer\n  error = \"Not Found\"; // This would cause an error in C#\n  ```\n\n`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_.\n\n### Dynamic vs. Static\n\n- The difference between dynamic typing and static typing lies in the **flexibility vs. the safety of your code**.\n\n- Dynamically typed languages offer **flexibility** but at the cost of **potential runtime errors\\***.\n\n- Statically typed languages **enforce a fixed variable type**.\n\n\u0026nbsp;\n\n## `undefined` vs `null`\n\n- `undefined` means a variable has been declared but hasn't been given a value yet.\n\n  ```javascript\n  let thingsBe;\n  console.log(thingsBe); // undefined\n  ```\n\n- `null` means the variable has been intentionally set to \"nothing\" and does not hold any value.\n\n  ```javascript\n  let go = null;\n  console.log(go); // null\n  ```\n\n\u0026nbsp;\n\n## Variable Naming Conventions\n\n1. Variable names should be **descriptive** and **meaningful**.\n   - it is best to **keep variable names readable** by using letters, numbers, underscores, or dollar signs.\n\n2. They **cannot** start with a `number`. They must begin with a `letter`, an underscore (`_`), or a dollar sign (`$`).\n\n   ```javascript\n\n   // invalid variable name\n   let 1stPlace;   // starts with a number\n\n   let age;\n   let _score;\n   let $total;\n   ```\n\n3. Variable names should **not** contain **spaces** or **special characters**, except for `_` and `$`.\n   - **Do not** use special characters like, exclamation points (`!`), or at (`@`) symbols in your variable names.\n\n4. Variable names should be `camelCase` like `cityName`, `isLoggedIn`, and `veryBigNumber`.\n   - 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_.\n\n     ```javascript\n     let age = 25;\n     let Age = 30;\n     console.log(age); // 25\n     console.log(Age); // 30\n     ```\n\n   - 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.\n\n     ```javascript\n     let thisIsCamelCase;\n     let anotherExampleVariable;\n     let freeCodeCampStudents;\n     ```\n\n5. Variable names should **not** be **reserved keywords**.\n   - 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_.\n\n\u0026nbsp;\n\n## `let`\n\n- The `let` keyword allows you to declare variables that can be updated or reassigned later.\n\n  ```javascript\n  let score = 10;\n  console.log(score); // 10\n  score = 20;\n  console.log(score); // 20\n  ```\n\n\u0026nbsp;\n\n## `const`\n\n- const is used to declare variables that are **constant**.\n\n- Once you assign a value to a variable declared with const, you **cannot reassign** it.\n\nThis makes const _ideal_ for values that **you don't want to change accidentally**, or otherwise, during the execution of the program.\n\n```javascript\nconst MAX_SIZE = 100;\nconsole.log(MAX_SIZE); // 100\n\n// Once MAX_SIZE is assigned the value 100, it cannot be changed.\n\nMAX_SIZE = 200; // This will result in an error\n```\n\n- Variables declared with `const` must be assigned a value at the time of declaration.\n\n  ```javascript\n  const PI; // Error: Missing initializer in const declaration\n  ```\n\n- Use const when you want to declare variables that should **remain constant**, like **configuration values** or **settings** that shouldn't be changed \\*accidentally\\*\\*\n\n`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_.\n\n\u0026nbsp;\n\n## \"Strings\"\n\nA string is a **sequence of characters** wrapped in either **single quotes** (`''`), **double quotes** (`\"\"`) or **backticks** (``).\n\n- Strings are **primitive** data types, and they are **immutable**.\n\n  ```js\n  let correctWay = \"This is a string\";\n  let alsoCorrect = \"This is also a string\";\n  ```\n\n- **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_.\n\n  ```js\n  let firstName = \"Sam\";\n  firstName = \"Sammy\"; // Reassigning the string to a new value\n  ```\n\n\u0026nbsp;\n\n## String Concatenation\n\n### w/ `+`\n\n- 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.\n\n- `+` operator is best for _simple concatenation_, especially when you need to combine a few strings or variables.\n\n  ```javascript\n  let firstName = \"John\";\n  let lastName = \"Doe\";\n\n  let fullName = firstName + lastName;\n  console.log(fullName); // \"JohnDoe\"\n  ```\n\n### w/ `+=`\n\n- if you need to **add or append** to an existing string, then you can use the `+=` operator.\n\n- `+=` operator is useful when building up a string step by step or _appending_ new content to an existing string variable.\n\n  ```javascript\n  let greeting = \"Hello\";\n  greeting += \", John!\";\n\n  console.log(greeting); // \"Hello, John!\"\n  ```\n\n### w/ `concat()`\n\n- `.concat()` method is beneficial when you need to _concatenate multiple strings_ together.\n\n  ```javascript\n  let firstName = \"John\";\n  let lastName = \"Doe\";\n  let fullName = firstName.concat(\" \", lastName);\n  console.log(fullName); // John Doe\n  ```\n\n  \u0026nbsp;\n\n## Working w/ \"Strings\"\n\nIn 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`.\n\n- 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...\n\n- 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...\n\n  ```js\n  let greeting = \"hello\";\n  console.log(greeting[1]); // \"e\"\n  ```\n\n- 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.\n  - in this case, the `length` of `hello` is `5`, and the last character (`o`) is at index `4` which is `5 - 1`.\n\n    ```js\n    let greeting = \"hello\";\n    console.log(greeting[greeting.length - 1]); // \"o\"\n    ```\n\n\u0026nbsp;\n\n## Escape Sequence Characters\n\n### `\\n` (Newline Character)\n\n- 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`.\n\n  ```js\n  /**\n   \"Roses are red,\n  Violets are blue,\n  JavaScript is fun,\n  And so are you.\" \n   **/\n  let poem =\n    \"Roses are red,\\nViolets are blue,\\nJavaScript is fun,\\nAnd so are you.\";\n  console.log(poem);\n  ```\n\n  \u0026nbsp;\n\n### Escaping String: `\\\"` (inner Quote)\n\n```js\nlet statement = \"She said, \"Hello!\"\"; //This will throw an error.(\n\nlet statement = \"She said, \\\"Hello!\\\"\";\nconsole.log(statement); // She said, \"Hello!\"\n```\n\n\u0026nbsp;\n\n### Escaping String: `\\'` (Single Quote)\n\n```js\nlet quote = \"It's a beautiful day!\";\nconsole.log(quote); // It's a beautiful day!\n```\n\n`Note`: The backslash (`\\`) tells JavaScript to treat the _quotes_ as **literal characters**, so they appear correctly in the output.\n\n\u0026nbsp;\n\n## Template Literals (``) \u0026 String interpolation (`${}`)\n\nTemplate 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_**.\n\n```js\nconst name = \"Alice\";\nconst age = 25;\nconst message = `My name is ${name} and I am ${age} years old.`;\n\nconsole.log(message);\n```\n\n- Supports **multi-line** strings.\n  - 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**:\n\n  ```js\n  let poem = `Roses are red,\n  Violets are blue,\n  JavaScript is fun,\n  And so are you.`;\n\n  console.log(poem);\n  ```\n\n- A **powerful** and **flexible** way to work with strings.\n  - Embed **JavaScript expressions directly within the string**, like in this example:\n\n  ```js\n  const song = \"Bohemian Rhapsody\";\n  const score = 9.5;\n  const highestScore = 10;\n  const output = `One of my favorite songs is \"${song}\". I rated it ${\n    (score / highestScore) * 100\n  }%.`;\n\n  console.log(output);\n  ```\n\n\u0026nbsp;\n\n## `indexOf()`\n\nTo **locate** the position of a **substring** inside of a _string_. it returns the **initial position** of the string starting with the index of `0`.\n\n```js\nlet sentence = \"JavaScript is awesome!\";\nlet position = sentence.indexOf(\"awesome!\");\n\nconsole.log(position); // 14\n```\n\n- if the substring is **not found**, `indexOf()` returns `-1`.\n\n  ```js\n  let sentence = \"JavaScript is awesome!\";\n  let position = sentence.indexOf(\"fantastic\");\n\n  console.log(position); // -1\n  ```\n\n- You can also specify **where to begin** searching within the string by providing a **second argument** to `indexOf()`.\n\n  ```js\n  let sentence = \"JavaScript is awesome, and JavaScript is powerful!\";\n  let position = sentence.indexOf(\"JavaScript\", 10);\n\n  console.log(position); // 27\n  ```\n\n- The `indexOf()` method is **case sensitive**.\n\n  ```js\n  console.log(\"freeCodeCamp\".indexOf(\"F\")); // -1\n  ```\n\n\u0026nbsp;\n\n## `includes()` method\n\nThe `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`.\n\n- **Case-sensitive**\n\n```js\nlet phrase = \"JavaScript is awesome!\";\nlet result = phrase.includes(\"awesome\");\n\nconsole.log(result); // true\n\nlet phrase = \"JavaScript is awesome!\";\nlet result = phrase.includes(\"Awesome\");\n\nconsole.log(result); // false\n```\n\n- 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:\n\n  ```js\n  let text = \"Hello, JavaScript world!\";\n  let result = text.includes(\"JavaScript\", 7);\n\n  console.log(result); // true\n  ```\n\n\u0026nbsp;\n\n## `slice()` method\n\nThe `slice()` method allows you to **extract a portion of a string** and **returns a new string**, without modifying the original string.\n\n- it takes two parameters: the **starting** index and the _optional_ **ending** index.\n\n  ```js\n  string.slice(startIndex, endIndex);\n  ```\n\n```js\nlet message = \"Hello, world!\";\nlet greeting = message.slice(0, 5);\n\nconsole.log(greeting); // Hello\n```\n\n- if you **omit the second parameter**, `slice()` will extract everything **from the start index to the end** of the string:\n\n  ```js\n  let message = \"Hello, world!\";\n  let world = message.slice(7);\n\n  console.log(world); // world!\n  ```\n\n- You can also use **negative numbers as indexes**. When you use a negative number, it **counts backward from the end** of the string:\n\n  ```js\n  let message = \"JavaScript is fun!\";\n  let lastWord = message.slice(-4);\n\n  console.log(lastWord); // fun!\n  ```\n\n\u0026nbsp;\n\n## `toUpperCase()`\n\nThe `toUpperCase()` method **converts all the characters to uppercase** letters and **returns a new string** with all uppercase characters.\n\n```js\nlet greeting = \"Hello, World!\";\nlet uppercaseGreeting = greeting.toUpperCase();\n\nconsole.log(uppercaseGreeting); // \"HELLO, WORLD!\"\n```\n\n\u0026nbsp;\n\n## `toLowerCase()`\n\nThe `toLowerCase()` method **converts all characters in a string to lowercase**.\n\n- Standardize input, such as when comparing **user-provided** text or making **case-insensitive** checks.\n\n```js\nlet shout = \"I AM LEARNING JAVASCRIPT!\";\nlet lowercaseShout = shout.toLowerCase();\n\nconsole.log(lowercaseShout); // \"i am learning javascript!\"\n```\n\n\u0026nbsp;\n\n## Trim Whitespace from a String\n\nWhen 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**,\n\n- Whitespace refers to **spaces**, **tabs**, or **line breaks** that occur in a string but are **not visible characters**.\n\n\u0026nbsp;\n\n### `trim()`\n\nThe `trim()` method is the most commonly used way to **remove whitespace** from both **the beginning** and **the end** of a string.\n\n- Removes all the leading and trailing spaces.\n\n```js\nlet message = \"   Hello!   \";\nconsole.log(message); // \"   Hello!   \"\n\nlet trimmedMessage = message.trim();\nconsole.log(trimmedMessage); // \"Hello!\"\n```\n\n`Note`: Any whitespace **within the string** (_between words_) is left **untouched** by `trim()`.\n\n\u0026nbsp;\n\n### `trimStart()`\n\n`trimStart()` removes whitespace from the **beginning** (_start_) of the string.\n\n```js\nlet greeting = \"   Hello!   \";\nconsole.log(greeting); // \"   Hello!   \"\n\nlet trimmedStart = greeting.trimStart();\nconsole.log(trimmedStart); // \"Hello!   \"\n```\n\n\u0026nbsp;\n\n### `trimEnd()`\n\n`trimEnd()` removes whitespace from the **end of the string**.\n\n```js\nlet greeting = \"   Hello!   \";\nconsole.log(greeting); // \"   Hello!   \"\n\nlet trimmedEnd = greeting.trimEnd();\nconsole.log(trimmedEnd); // \"   Hello!\"\n```\n\n\u0026nbsp;\n\n## `replace()` method\n\nThe `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.\n\n```js\nstring.replace(searchValue, newValue);\n```\n\n- Case-sensitive\n\n- `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.\n\n- The `newValue` is the value that will **replace** the `searchValue`.\n\n  ```js\n  let text = \"I love JavaScript!\";\n  console.log(text); // \"I love JavaScript!\"\n\n  let newText = text.replace(\"JavaScript\", \"Elixir\");\n  console.log(newText); // \"I love Elixir!\"\n  ```\n\n`Note`: By default, the `replace()` method will only **replace the first occurrence** of the `searchValue`.\n\n\u0026nbsp;\n\n### `replaceAll()` method\n\nit replaces all of the occourences of the `searchValue`.\n\n\u0026nbsp;\n\n## `repeat()` method\n\nThe `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**.\n\n```js\nstring.repeat(count);\n```\n\n- `string` is the string that you want to **repeat**, and `count` is the _number of times_ you want the string to be repeated.\n\n  ```js\n  let word = \"Hello!\";\n  let repeatedWord = word.repeat(3);\n  console.log(repeatedWord); // \"Hello!Hello!Hello!\"\n  ```\n\n- The `count` parameter must be a **non-negative** number. if you pass a negative number, JavaScript will throw a `RangeError`.\n\n  ```js\n  let word = \"Test\";\n  console.log(word.repeat(-1)); // Throws RangeError: Invalid count value\n  ```\n\n- 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`.\n\n  ```js\n  let word = \"Test\";\n  console.log(word.repeat(Infinity)); // Throws RangeError: Invalid count value\n  ```\n\n  - 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_.\n\n- 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.\n\n  ```js\n  let word = \"Test\";\n  console.log(word.repeat(2.5)); // \"TestTest\"\n  ```\n\n- if you pass `0` as the `count`, the `repeat()` method will return an empty string (`\"\"`).\n\n\u0026nbsp;\n\n## `prompt()` method\n\nOne of the simplest ways to **get input from a user** through a small **pop-up dialog** box.\n\n```js\nprompt(message, default);\n```\n\n- Basic Example\n\n  ```js\n  const btn = document.getElementById(\"prompt-btn\");\n  const output = document.getElementById(\"output\");\n\n  btn.addEventListener(\"click\", () =\u003e {\n    const userName = prompt(\"What is your name?\", \"User\");\n    output.textContent = \"Hello, \" + userName + \"!\";\n  });\n  ```\n\n  - Returns the input as a **string**.\n\n  - `null` signifies that the user **did not** provide any **input**.\n\n  - `prompt()` method will **halt the execution** of the script **until the user interacts** with the _dialog box_.\n\n\u0026nbsp;\n\n`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_.\n\n\u0026nbsp;\n\n## American Standard Code for Information Interchange (`ASCII`)\n\nASCII is **a system for encoding characters** such as letters, digits, and symbols into **numerical** values.\n\n- Each **character** is mapped to a **specific** number.\n\n- For example, `A` is represented by the number `65`, while `a` is represented by `97`.\n\n- JavaScript strings use Unicode (`UTF-16`) internally, ASCII values match the first `128` Unicode characters.\n  - Uppercase and lowercase English letters (`A-Z`, `a-z`).\n  - Numbers (`0-9`).\n  - Common punctuation marks and symbols (`!`, `@`, `#`, and _so on_).\n  - Control characters (such as **newline** and **tab**).\n\nin 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.\n\n```js\nlet letter = \"A\";\nconsole.log(letter.charCodeAt(0)); // 65\n```\n\nThe `fromCharCode()` method allows you to do the **opposite**: convert a **UTF-16** code unit (which matches ASCII for basic characters) into its **corresponding character**.\n\n```js\nlet char = String.fromCharCode(65);\nconsole.log(char); //  A\n\nlet char = String.fromCharCode(97);\nconsole.log(char); // a\n```\n\n`Note`: These methods are particularly useful when you need to **manipulate or compare characters based on their numeric code values**.\n\n\u0026nbsp;\n\n## A Semicolon (`;`)\n\nSemicolons 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.\n\n- Semicolons help **delineate statements**, and improve _code readability_ and \\*reliability\\*\\*.\n\n  ```js\n  let message = \"Hello, World!\"; // first statement ends here\n  let number = 42; // second statement starts here\n  ```\n\nJust as a period (`.`) marks the **end of a sentence** in _English_, a semicolon (`;`) signifies the **end of an executable line of code** in _JavaScript_.\n\n- This allows the JavaScript engine to distinguish between separate commands.\n\nWithout the semicolon, the JavaScript engine \\*might\\*\\* have trouble interpreting where one statement ends and another begins.\n\n- Semicolons help **prevent ambiguities** in code execution and ensure that statements are _correctly terminated_.\n\n\u0026nbsp;\n\n`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.\n\n\u0026nbsp;\n\n## Comments in JavaScript\n\nAny 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**.\n\n- They are there solely for the benefit of people **reading the code**, whether that's you or someone else.\n\n- The comment provides important context for why \"this\" code _exists_.\n\n### Single line (`//`)\n\n```js\n// I am a single line comment in JavaScript\n```\n\n### Multi-line (`/* */`)\n\n```js\n/*\n I am a multiline comment.\n This is helpful for longer explanations.\n*/\n```\n\nWhile 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.\n\n\u0026nbsp;\n\n`Note`: The goal is to **enhance readability**, **do not clutter** the code with _unnecessary_ explanations.\n\n\u0026nbsp;\n\n## Data Types in JavaScript\n\n- `Number`: A number represents both **integers** and **floating-point** values.\n  - Examples of integers include 7, 19, and 90.\n\n- **Floating point**: A floating point number is a number with a **decimal** point.\n  - Examples include 3.14, 0.5, and 0.0001.\n\n  - 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.\n\n- `String`: A string is a **sequence of characters**, or **text**, enclosed in **quotes**.\n  - `\"I like coding\"` and `'JavaScript is fun'` are examples of strings.\n\n- `Boolean`: A boolean represents one of two possible values: `true` or `false`.\n  - To represent a condition, such as `isLoggedIn = true`.\n\n- `Undefined`: An undefined value is a variable that has been declared but **not assigned** a value.\n\n- `Null`: A value is an `empty` value, or a variable that has `intentionally` been assigned a value of null.\n\n- `Object`: An object is a collection of **key-value** pairs. The key is the property _name_, and the value is the property _value_.\n  - Here, the `pet` object has three properties or **keys**: `name`, `age`, and `type`. The values are `Fluffy`, `3`, and `dog`, respectively.\n\n    ```js\n    let pet = {\n      name: \"Fluffy\",\n      age: 3,\n      type: \"dog\",\n    };\n    ```\n\n- `Symbol`: The Symbol data type is a **unique** and **immutable** value that may be used as an **identifier** for object properties.\n  - in this example below, two symbols are created with the **same description**, but they are **not equal**.\n\n    ```js\n    const crypticKey1 = Symbol(\"saltNpepper\");\n    const crypticKey2 = Symbol(\"saltNpepper\");\n    console.log(crypticKey1 === crypticKey2); // false\n    ```\n\n- `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**.\n  - By adding an `n` to the end of the number, you can create a BigInt.\n\n    ```js\n    const veryBigNumber = 1234567890123456789012345678901234567890n;\n    ```\n\n\u0026nbsp;\n\n## `typeof` Operator\n\nThe typeof operator is used to **check the data type of a variable**. it returns a _string_ indicating the _type_ of the variable.\n\n```js\nlet age = 25;\nconsole.log(typeof age); // \"number\"\n\nlet isLoggedIn = true;\nconsole.log(typeof isLoggedIn); // \"boolean\"\n```\n\n- However, there's a well-known \"_quirk_\"/_bug_ in JavaScript when it comes to `null`. The `typeof` operator returns `\"object\"` for `null` values.\n\n  ```js\n  let user = null;\n  console.log(typeof user); // \"object\"\n  ```\n\n  When the language was first implemented, values like `null` were represented as a **\"special\" type of object**, leading to this _unexpected_ result.\n\n  _Unfortunately_, this has become **a part of the language**, and while it's confusing, it's something **you'll need to be aware of**.(\n\n\u0026nbsp;\n\n## Number\n\nThe `Number` data type represents a **numeric** value. JavaScript uses one unified `Number` type to account for numbers.\n\n```js\nconst wholeNumber = 50;\nconst decimalNumber = 4.5;\nconst negativeNumber = -7;\n\nconsole.log(typeof wholeNumber); // number\nconsole.log(typeof decimalNumber); // number\nconsole.log(typeof negativeNumber); // number\n```\n\n- 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`.\n  - 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.\n\n    ```js\n    const infiniteNumber = 1 / 0;\n    console.log(infiniteNumber); // Infinity\n    console.log(typeof infiniteNumber); // number\n    ```\n\n  - in JavaScript, some mathematical operations **don't result in a valid number**, i.e., why `NaN`, which stands for \"Not a Number\".\n\n    ```js\n    const notANumber = \"hello world\" / 2;\n    console.log(notANumber); // NaN\n    console.log(typeof notANumber); // number\n    ```\n\n\u0026nbsp;\n\n`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.\n\n\u0026nbsp;\n\n## Arithmetic Operators\n\nJavaScript provides tools to perform basic _arithmetic operations_ on numbers, such as **addition** (`+`), **subtraction** (`-`), **multiplication** (`*`), and **division** (`/`).\n\n- JavaScript also includes operators for more _complex_ arithmetic operations, such as **remainder** (`%`) and **exponentiation** (`**`).\n\n\u0026nbsp;\n\n`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.\n\n\u0026nbsp;\n\n## Calculations with `Numbers` and `Strings`\n\nJavaScript 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.\n\n- **Type coercion** is when a value from one data type is converted into another.\n\n\u0026nbsp;\n\n### Number + String = String concatenation\n\nin JavaScript, the `+` operator does **double duty**. It handles both **addition** and **string concatenation**.\n\n```js\nconst result = 5 + \"10\";\n\nconsole.log(result); // 510\nconsole.log(typeof result); // string\n```\n\n- 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!\n\n  ```js\n  const subtractionResult = \"10\" - 5;\n  console.log(subtractionResult); // 5\n  console.log(typeof subtractionResult); // number\n\n  const multiplicationResult = \"10\" * 2;\n  console.log(multiplicationResult); // 20\n  console.log(typeof multiplicationResult); // number\n\n  const divisionResult = \"20\" / 2;\n  console.log(divisionResult); // 10\n  console.log(typeof divisionResult); // number\n  ```\n\n- But what if the **string isn't a number**? (`NaN`)\n\n  ```js\n  const subtractionResult = \"abc\" - 5;\n  console.log(subtractionResult); // NaN\n  console.log(typeof subtractionResult); // number\n\n  const multiplicationResult = \"abc\" * 2;\n  console.log(multiplicationResult); // NaN\n  console.log(typeof multiplicationResult); // number\n\n  const divisionResult = \"abc\" / 2;\n  console.log(divisionResult); // NaN\n  console.log(typeof divisionResult); // number\n  ```\n\n  - 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_\".\n\n- JavaScript treats **booleans as numbers** in mathematical operations: `true` becomes `1`, and `false` becomes `0`.\n\n  ```js\n  const result1 = true + 1;\n  console.log(result1); // 2\n  console.log(typeof result1); // number\n\n  const result2 = false + 1;\n  console.log(result2); // 1\n  console.log(typeof result2); // number\n\n  const result3 = \"Hello\" + true;\n  console.log(result3); // \"Hellotrue\"\n  console.log(typeof result3); // string\n  ```\n\n- JavaScript treats `null` as `0` and `undefined` as `NaN` in mathematical operations.\n\n  ```js\n  const result1 = null + 5;\n  console.log(result1); // 5\n  console.log(typeof result1); // number\n\n  const result2 = undefined + 5;\n  console.log(result2); // NaN\n  console.log(typeof result2); // number\n  ```\n\n\u0026nbsp;\n\n`Note`: JavaScript often performs **type coercion**, _automatically_ converting data types such as numbers, strings, and booleans in sometimes **unexpected ways**.\n\n\u0026nbsp;\n\n## Operator Precedence\n\nOperator 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.\n\n- Operators with **higher** precedence are evaluated before those with **lower** precedence.\n\n  ```js\n  const result = 2 + 3 * 4;\n  console.log(result); // 14\n\n  const result = 2 + 6 / 3;\n  console.log(result); // 4\n  ```\n\n- Similar to mathematics, you can use parentheses `()` around certain parts of your expression to run _first_, **regardless of precedence** rules.\n\n  ```js\n  const result = (2 + 3) * 4;\n  console.log(result); // 20\n  ```\n\n- **Associativity** is what tells JavaScript whether to evaluate operators from **left to right** or **right to left**.\n  - For most operators like **addition** and **multiplication**, associativity is **_left to right_**.\n\n    ```js\n    const result = 10 - 2 + 3;\n    console.log(result); // 11\n    ```\n\n  - Some operators, like assignment (`=`), are **right-to-left** associative. This means the right side of the expression gets evaluated first.\n\n    ```js\n    let a, b;\n    a = b = 5;\n\n    console.log(a); // 5\n    console.log(b); // 5\n    console.log(a + b); // 10\n    ```\n\n  - The exponent operator (`**`) is also **right-to-left** associative.\n\n    ```js\n    const result = 2 ** (3 ** 2);\n    console.log(result); // 512\n    ```\n\n\u0026nbsp;\n\n## increment and Decrement Operators\n\nThe increment and decrement operators are represented by `++` and `--`, respectively. They both allow you to adjust the value of a variable by `1`.\n\n- 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`.\n  - it's faster, cleaner, and easier to read.\n\n- **Prefix** \u0026 **Postfix**\n  - Prefix (`++x`) **increases** the value of the variable **first**, then returns a new value.\n\n    ```js\n    let x = 5;\n\n    console.log(++x); // 6\n    console.log(x); // 6\n    ```\n\n  - Postfix (`x++`) **returns** the current value of the variable **first**, then increases it.\n\n    ```js\n    let y = 5;\n\n    console.log(y++); // 5\n    console.log(y); // 6\n    ```\n\n\u0026nbsp;\n\n`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**.\n\n\u0026nbsp;\n\n## Compound Assignment Operators\n\nCompound 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**.\n\n- 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.\n\n  ```js\n  let total = 10;\n  total += 5;\n\n  console.log(total); // 15\n  ```\n\n  - There's a **subtraction** assignment operator (`-=`)\n\n  - The **multiplication** assignment operator (`*=`)\n\n  - Lastly, there's a **division** assignment operator (`/=`)\n\n- There's a compound assignment operator for every operator in JavaScript. So, apart from the four already mentioned, we also have...\n  - **Remainder assignment** operator (`%=`), which divides a variable by the specified number and assigns the remainder to the variable.\n\n  - **Exponent assignment** operator (`**=`), which raises a variable to the power of the specified number and reassigns the result to the variable.\n\n  - **Bitwise AND assignment** operator (`\u0026=`), which performs a bitwise AND operation with the specified number and reassigns the result to the variable.\n\n  - **Bitwise OR assignment** operator (`|=`), which performs a bitwise OR operation with the specified number and reassigns the result to the variable.\n\n\u0026nbsp;\n\n## Booleans, Equality and inequality Operators\n\nBooleans are a data type with only `true` and `false` values. They're useful because they allow you to do something based on some **conditions**.\n\n- 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`.\n\n```js\n// equality: performs type coercion\nconsole.log(5 == \"5\"); // true\n\n// strict equality\nconsole.log(5 === \"5\"); // false\n\n// inequality\nconsole.log(5 != \"5\"); // false\n\n// strict inequality\nconsole.log(5 !== \"5\"); // true\n```\n\n- Type coercion converts the **string** value to a **number** and then _compares_ the values.\n\n\u0026nbsp;\n\n`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.\n\n\u0026nbsp;\n\n## Comparison Operators\n\nComparison 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.\n\n- The greater than operator (`\u003e`), checks if the value on the _left_ is **greater** than the one on the _right_.\n\n  ```js\n  let a = 6;\n  let b = 9;\n\n  console.log(a \u003e b); // false\n  console.log(b \u003e a); // true\n  ```\n\n- The greater than or equal operator (`\u003e=`), checks if the value on the _left_ is **either greater than or equal** to the one on the _right_.\n\n  ```js\n  let a = 6;\n  let b = 9;\n  let c = 6;\n\n  console.log(a \u003e= b); // false\n  console.log(b \u003e= a); // true\n  console.log(a \u003e= c); // true\n  ```\n\n- The lesser than operator (`\u003c`) checks if the value on the _left_ is **smaller** than the one on the _right_.\n\n  ```js\n  let a = 6;\n  let b = 9;\n\n  console.log(a \u003c b); // true\n  console.log(b \u003c a); // false\n  ```\n\n- The less than or equal operator (`\u003c=`) checks if the value on the _left_ is **smaller than or equal** to the one on the _right_.\n\n  ```js\n  let a = 6;\n  let b = 9;\n  let c = 6;\n\n  console.log(a \u003c= b); // true\n  console.log(b \u003c= a); // false\n  console.log(a \u003c= c); // true\n  ```\n\n\u0026nbsp;\n\n## `null` vs. `undefined`\n\nin JavaScript, `null` and `undefined` are two distinct data types that **represent the absence of a value**, but they **behave differently** in comparisons.\n\n- 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*.\n\n- 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**.\n\n### w/ Equality Operator (`==`)\n\nWhen 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**.\n\n```js\nconsole.log(null == undefined); // true\n```\n\nThe comparisons below return `false` because `null` and `undefined` are **only equal to each other (and themselves)** when using the **equality operator**.\n\n```js\nconsole.log(null == 0);  // false\nconsole.log(null == ''); // false\nconsole.log(undefined == 0); // false\nconsole.log(undefined == ''); // false\n```\n\nTricky AF.\n\n```js\nconsole.log(null \u003e 0);  // false\nconsole.log(null == 0); // false\nconsole.log(null \u003e= 0); // true\n```\n\n`undefined`, on the other hand, **always converts to `NaN`** in numeric contexts, which makes **all numeric comparisons with `undefined` return `false`**.\n\n```js\nconsole.log(undefined \u003e 0);  // false\nconsole.log(undefined \u003c 0);  // false\nconsole.log(undefined == 0); // false\n```\n\n### w/ Strict Equality Operator (`===`)\n\nHowever, when using the **strict equality operator**, which checks both value and type **without performing type coercion**, `null` and `undefined` are **not equal**.\n\n```js\nconsole.log(null === undefined); // false\n```\n\n\u0026nbsp;\n\n`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*.\n\n\u0026nbsp;\n\n## Unary Operators\n\nUnary operators act on a **single operand to perform operations** like **type conversion**, **value manipulation**, or checking certain **conditions**.\n\n- The **unary plus** operator **converts its operand into a number**. If the operand is already a number, it remains unchanged.\n  - Unary plus is handy when you want to **make sure** you're working with **a numeric value**.\n\n  ```js\n  const str = \"42\";\n  const strToNum = +str;\n\n  console.log(strToNum); // 42\n  console.log(typeof str); // string\n  console.log(typeof strToNum); // number\n  ```\n\n- 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 `-`.\n\n  ```js\n  const str = \"42\";\n  const strToNegativeNum = -str;\n\n  console.log(strToNegativeNum); // -42\n  console.log(typeof str); // string\n  console.log(typeof strToNegativeNum); // number\n  ```\n\n- 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`.\n\n  ```js\n  let isOnline = true;\n  console.log(!isOnline); // false\n\n  let isOffline = false;\n  console.log(!isOffline); // true\n  ```\n\n- The `void` keyword is a unary operator that **evaluates an expression** and **returns** `undefined`.\n\n  ```js\n  const result = void (2 + 2);\n\n  console.log(result); // undefined\n  ```\n\n  - `void` is also commonly used in _hyperlinks_ to **prevent navigation**.\n\n    ```js\n    \u003ca href=\"javascript:void(0);\"\u003eClick Me\u003c/a\u003e\n    ```\n\n- The `typeof` operator **returns the type** of its operand as a **string**.\n\n  ```js\n  const value = \"Hello world\";\n\n  console.log(typeof value); // string\n  ```\n\n- 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**.\n\n  ```js\n  const num = 5; // The binary for 5 is 00000101\n\n  console.log(~num); // -6\n  ```\n\n  - 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**.\n\n\u0026nbsp;\n\n## Bitwise Operators\n\nBitwise operators in JavaScript are special operators that **work on the binary representation of numbers**.\n\n- A **bit** is the most basic unit of information.\n  - it can have only two values: `0` or `1`.\n\n- **Binary** is a **number system** that uses only `0` and `1` to represent all numbers.\n  - in binary, each digit represents a **power of** `2`, _starting_ from the **rightmost** digit and _increasing_ as we move **left**.\n\n    ```\n    - 10 in binary is 1010\n\n    1              0               1               0\n    1*(2**3) = 8   0*(2**2) = 0    1*(2**1) = 2    0*(2**0) = 0   =\u003e 8+0+2+0 = 10\n    ```\n\n- **Bitwise operators** perform **operations on the binary representation** of numbers.\n  - The bitwise **AND** (`\u0026`) operator **returns** a `1` in each bit position for which the corresponding bits of both operands are `1`.\n\n    ```js\n    let a = 5; // Binary: 101\n    let b = 3; // Binary: 011\n    console.log(a \u0026 b); // 1 (Binary: 001)\n    ```\n\n  - The bitwise **OR** (`|`) operator **returns** a `1` in each bit position for which the corresponding bits of either or both operands are `1`.\n\n    ```js\n    let a = 5; // Binary: 101\n    let b = 3; // Binary: 011\n    console.log(a | b); // 7 (Binary: 111)\n    ```\n\n  - The bitwise **XOR** (`^`) operator **returns** a `1` in each bit position for which the corresponding bits of either, but not both, operands are `1`.\n\n    ```js\n    let a = 5; // Binary: 101\n    let b = 3; // Binary: 011\n    console.log(a ^ b); // 6 (Binary: 110)\n    ```\n\n  - The bitwise **NOT** (`~`) operator **inverts** all the **bits** of its operand.\n\n    ```js\n    let a = 5; // Binary: 101\n    console.log(~a); // -6\n    ```\n\n    - This might seem surprising, but it's because of how negative numbers are represented in binary using two's complement.\n\n  - The left shift (`\u003c\u003c`) operator **shifts** all bits to the **left** by a specified number of positions.\n\n    ```js\n    let a = 5; // Binary: 101\n    console.log(a \u003c\u003c 1); // 10 (Binary: 1010)\n    ```\n\n    - Here, all bits are shifted one position to the left, effectively **multiplying** the number by `2`.\n\n  - The right shift (`\u003e\u003e`) operator **shifts** all bits to the **right**.\n\n    ```js\n    let a = 5; // Binary: 101\n    console.log(a \u003e\u003e 1); // 2 (Binary: 10)\n    ```\n\n    - Here, all bits are shifted one position to the right, effectively **dividing** the number by `2` and rounding down.\n\n\u0026nbsp;\n\n`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**.\n\n\u0026nbsp;\n\n## Conditional Statements\n\nConditional statements let you **make decisions** in your JavaScript code. They allow your program to flow in a particular way **based on certain conditions**.\n\n- 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.\n  - non-empty strings\n\n  - **any other number** than `0` and `-0`\n\n  - arrays\n\n  - objects\n\n  - the boolean `true`\n\n- Falsy values are values that evaluate to `false` in a boolean context.\n  - boolean `false`\n\n  - `0` (zero)\n\n  - `\"\"` (empty string)\n\n  - `null`\n\n  - `undefined`\n\n  - `NaN` (Not a Number)\n\n  ```js\n  if (null) {\n    console.log(\"This will not run.\");\n  }\n\n  if (\"freeCodeCamp\") {\n    console.log(\"This will run.\");\n  }\n  ```\n\n- When a condition is `false`, then you can use an `else` clause:\n\n  ```js\n  const age = 15;\n\n  if (age \u003e= 18) {\n    console.log(\"You're eligible to vote\");\n  } else {\n    console.log(\"You're not eligible to vote\"); // You're not eligible to vote\n  }\n  ```\n\n- When you want to check **multiple conditions**, you can use an `else if` block.\n\n  ```js\n  const score = 87;\n\n  if (score \u003e= 90) {\n    console.log(\"You got an A\");\n  } else if (score \u003e= 80) {\n    console.log(\"You got a B\"); // You got a B\n  } else if (score \u003e= 70) {\n    console.log(\"You got a C\");\n  } else {\n    console.log(\"You failed! You need to study more!\");\n  }\n  ```\n\n\u0026nbsp;\n\n## Ternary Operator (`?:`)\n\nThe **ternary operator** is a compact way to write **simple if/else statements**.\n\n  ```js\n  condition ? expressionIfTrue : expressionIfFalse;\n  ```\n\n  ```js\n  const temperature = 30;\n  const weather = temperature \u003e 25 ? \"sunny\" : \"cool\";\n\n  console.log(`It's a ${weather} day!`);\n  ```\n\n\u0026nbsp;\n\n## Switch Case\n\nA `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. \n\n```js\nswitch (expression) {\n  case value1:\n    // code to be executed if expression === value1\n    break;\n  case value2:\n    // code to be executed if expression === value2\n    break;\n  default:\n    // code to be executed if expression doesn't match any case\n}\n```\n\n- 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**\".\n\n### When to Use\n\n`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**.\n\n```js\nlet dayOfWeek = 3; \n\nswitch (dayOfWeek) {\n    case 1:\n        console.log(\"It's Monday! Time to start the week strong.\");\n        break;\n    case 2:\n        console.log(\"It's Tuesday! Keep the momentum going.\");\n        break;\n    case 3:\n        console.log(\"It's Wednesday! We're halfway there.\");\n        break;\n    case 4:\n        console.log(\"It's Thursday! Almost the weekend.\");\n        break;\n    case 5:\n        console.log(\"It's Friday! The weekend is near.\");\n        break;\n    case 6:\n        console.log(\"It's Saturday! Enjoy your weekend.\");\n        break;\n    case 7:\n        console.log(\"It's Sunday! Rest and recharge.\");\n        break;\n    default:\n        console.log(\"Invalid day! Please enter a number between 1 and 7.\");\n}\n```\n\n- `switch` statements can be more **readable** and **concise** when dealing with **many possible values** for a **single variable**.\n\n- `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*.\n\n### When Not to Use\n\n`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**.\n\n```js\nlet creditScore = 720; \nlet annualIncome = 60000; \nlet loanAmount = 200000; \n\nlet eligibilityStatus;\n\nif (creditScore \u003e= 750 \u0026\u0026 annualIncome \u003e= 80000) {\n    eligibilityStatus = \"Eligible for premium loan rates.\";\n} else if (creditScore \u003e= 700 \u0026\u0026 annualIncome \u003e= 50000) {\n    eligibilityStatus = \"Eligible for standard loan rates.\";\n} else if (creditScore \u003e= 650 \u0026\u0026 annualIncome \u003e= 40000) {\n    eligibilityStatus = \"Eligible for subprime loan rates.\";\n} else if (creditScore \u003c 650) {\n    eligibilityStatus = \"Not eligible due to low credit score.\";\n} else {\n    eligibilityStatus = \"Not eligible due to insufficient income.\";\n}\n\nconsole.log(eligibilityStatus);\n```\n\n\u0026nbsp;\n\n`Note`: `switch` statements **excel at handling multiple possible values for a \"single variable\"**, while `if/else if` chains offer **more flexibility for complex conditions**.\n\n\u0026nbsp;\n\n## Binary Logical Operators\n\nBinary logical operators help you **evaluate** two expressions and return a result based on their **truthiness**.\n\n### Logical AND (`\u0026\u0026`)\n\nit checks if **both** operands are **true** and returns a result.\n\n- if **both** operands are **truthy**, it _returns_ the **second value**, that is, the one on the **right**:\n\n  ```js\n  const result = true \u0026\u0026 \"hello\";\n\n  console.log(result); // hello\n  ```\n\n- if **either** operand is **falsy**, it _returns_ the **falsy value**:\n\n  ```js\n  const result = 0 \u0026\u0026 3;\n\n  console.log(result); // 0\n  ```\n\n- if **both** operands are **falsy**, it _returns_ the first **falsy value**:\n\n  ```js\n  const result = false \u0026\u0026 0;\n\n  console.log(result); // false\n  ```\n\n- The **logical AND** operator is useful when you want to **check multiple conditions** and ensure that all are **true** before proceeding.\n\n  ```js\n  if (2 \u003c 3 \u0026\u0026 3 \u003c 4) {\n    console.log(\"The if block runs\");\n  } else {\n    console.log(\"The else block runs\");\n  }\n  ```\n\n### Logical OR (`||`)\n\nThis operator checks if at least **one** of the operands is **truthy**. if the first operand is **truthy**, it **returns** that value:\n\n```js\nconst result = \"This is truthy\" || false;\n\nconsole.log(result); // This is truthy\n```\n\n- if the **first** operand is **falsy** but the **second** is **truthy**, the **second value will be logged** to the console:\n\n  ```js\n  const result = 0 || \"This is truthy\";\n\n  console.log(result); // This is truthy\n  ```\n\n- An example:\n\n  ```js\n  let userInput;\n  \n  if (userInput || 'Guest') {\n   console.log('A user is present');\n  } else {\n   console.log('No user detected');\n  }\n  ```\n\n### Nullish Coalescing (`??`)\n\nit helps in scenarios where you want to **return** a value **only if** the **first value** is `null` or `undefined`.\n\n```js\nconst result = null ?? 'default';\n\nconsole.log(result); // default\n```\n\n- 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.\n\n  ```js\n  const userSettings = {\n   theme: null,\n   volume: 0,\n   notifications: false,\n  };\n\n  let theme = userSettings.theme ?? 'light';\n  console.log(theme); // light\n  ```\n\n\u0026nbsp;\n\n## The Math Object\n\nWhile basic arithmetic operators can handle simple calculations, JavaScript offers a *built-in* Math object to tackle more **complex math** challenges.\n\n### `Math.random()`\n\nThis method **generates a random floating-point number** between `0` (*inclusive*) and `1` (*exclusive*). \n\n- This means the possible output can be `0`, but it will never actually reach `1`. \n\n  ```js\n  const randomNum = Math.random();\n\n  console.log(randomNum);\n  // any number between 0 and 1 – 0 inclusive and 1 exclusive\n  ```\n\n### `Math.min()` \u0026 `Math.max()`\n\nThey both take **a set of numbers** and return the **minimum** and **maximum** value, *respectively*.\n\n```js\nconst smallest = Math.min(1, 5, 3, 9);\nconsole.log(smallest); // 1\n\nconst largest = Math.max(1, 5, 3, 9);\nconsole.log(largest); // 9\n```\n\n### `Math.ceil()` \u0026 `Math.floor()`\n\nif you wanted to **round numbers up or down** to the nearest whole integer, you could use the `Math.ceil()` and `Math.floor()` methods.\n\n```js\nconsole.log(Math.ceil(4.3)); // 5\n\nconsole.log(Math.floor(4.7)); // 4\n```\n\n### `Math.round()`\n\nMath.round() is the **hybrid** of `Math.ceil()` and `Math.floor()`. it **rounds a number** to its nearest integer, **taking the decimal point into account**:\n\n```js\nconsole.log(Math.round(2.3)); // 2\nconsole.log(Math.round(4.5)); // 5\nconsole.log(Math.round(4.8)); // 5\n```\n\n- if the decimal point is **less than 5**, the number is **rounded down**. \n- And if the decimal point is **5 or greater**, the number is **rounded up**. \n\n### Random Number Generator\n\n```js\nMath.floor(Math.random() * (maximum - minimum) + minimum);\n```\n\nGenerating a random number between two whole numbers.\n\n```js\nconst max = 10;\nconst min = 5;\nconst randomNum = Math.floor(Math.random() * (max - min + 1)) + min;\nconsole.log(randomNum);\n\n// Generating a random number between 20 and 1\nconst randomNumBtw1And20 = Math.floor(Math.random() * 20) + 1;\nconsole.log(randomNumBtw1And20);\n```\n\n### `Math.trunc()`\n\nit **removes the decimal part** of a number, returning only the integer portion, **without rounding**.\n\n```js\nconsole.log(Math.trunc(2.9)); // 2\nconsole.log(Math.trunc(9.1)); // 9\n```\n\n### `Math.sqrt()` \u0026 `Math.cbrt()`\n\nIf you need to get the **square root** or **cube root** of a number, you can use the Math.sqrt() and Math.cbrt() methods, respectively.\n\n```js\nconsole.log(Math.sqrt(81)); // 9\nconsole.log(Math.cbrt(27)); // 3\n```\n\n### `Math.abs()`\n\nif 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**.\n\n```js\nconsole.log(Math.abs(-5)); // 5\nconsole.log(Math.abs(5)); // 5\n```\n\n### `Math.pow()`\n\nit takes two numbers and **raises the second as the power to the first**.\n\n```js\nconsole.log(Math.pow(2, 3)); // 8\nconsole.log(Math.pow(8, 2)); // 64\n```\n\n\u0026nbsp;\n\n## Not a Number (`NaN`)\n\nIt'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.\n\n- `NaN` is typically the result of operations that should return a number but **cannot produce a meaningful numerical value**.\n\n  ```js\n  let result = 0 / 0;\n  console.log(result); // NaN\n  ```\n\n  - Dividing zero by zero is mathematically **undefined**, so JavaScript returns `NaN`.\n\n- One peculiar property of `NaN` is that **it is not equal to anything**, including *itself*.\n\n  ```js\n  console.log(NaN === NaN); // false\n  ```\n\n### `isNaN()`\n\nThe `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.\n\n```js\nconsole.log(isNaN(NaN));       // true\nconsole.log(isNaN(undefined)); // true\nconsole.log(isNaN({}));        // true\n\nconsole.log(isNaN(true));      // false\nconsole.log(isNaN(null));      // false\nconsole.log(isNaN(37));        // false\n\nconsole.log(isNaN(\"37\"));      // false: \"37\" is converted to 37\nconsole.log(isNaN(\"37.37\"));   // false: \"37.37\" is converted to 37.37\nconsole.log(isNaN(\"\"));        // false: empty string is converted to 0\nconsole.log(isNaN(\" \"));       // false: string with a space is converted to 0\n\nconsole.log(isNaN(\"blabla\"));  // true: \"blabla\" is not a number\n```\n\n### `Number.isNaN()`\n\nit **does not perform type coercion** before testing. it only returns `true` if the value is exactly `NaN`.\n\n- introduced in **ES6**\n\n```js\nconsole.log(Number.isNaN(NaN));        // true\nconsole.log(Number.isNaN(Number.NaN)); // true\nconsole.log(Number.isNaN(0 / 0));      // true\n\nconsole.log(Number.isNaN(\"NaN\"));      // false\nconsole.log(Number.isNaN(undefined));  // false\nconsole.log(Number.isNaN({}));         // false\nconsole.log(Number.isNaN(\"blabla\"));   // false\n```\n\n  - `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.\n\n### `NaN` Based Error Handling\n\nwhen 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.\n\n```js\nlet a = 0;\nlet b = 0;\nlet result = a / b;\n\nif (Number.isNaN(result)) {\n  result = \"Error: Division resulted in NaN\";\n}\n\nconsole.log(result); // \"Error: Division resulted in NaN\"\n```\n\n\u0026nbsp;\n\n## `parseFloat()` \u0026 `parseInt()` Methods\n\nThese 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.\n\n### `parseFloat()` \n\nThis method parses a **string** argument and returns a **floating-point** number. it is designed to *extract* a number from the **beginning** of a string.\n\n```js\nconsole.log(parseFloat(\"3.14\"));     // 3.14\nconsole.log(parseFloat(\"3.14 abc\")); // 3.14\nconsole.log(parseFloat(\"3.14.5\"));   // 3.14\nconsole.log(parseFloat(\"abc 3.14\")); // NaN\n```\n\n### `parseInt()`\n\nThis 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**.\n\n```js\nconsole.log(parseInt(\"42\"));       // 42\nconsole.log(parseInt(\"42px\"));     // 42\nconsole.log(parseInt(\"3.14\"));     // 3\nconsole.log(parseInt(\"abc123\"));   // NaN\n```\n\n- They both **ignore leading whitespace**.\n\n  ```js\n  console.log(parseFloat(\"  3.14\"));  // 3.14\n  console.log(parseInt(\"  42\"));      // 42\n  ```\n\n- They both handle **plus and minus signs** at the beginning of the string.\n\n  ```js\n  console.log(parseFloat(\"+3.14\"));  // 3.14\n  console.log(parseInt(\"-42\"));      // -42\n  ```\n\n\u0026nbsp;\n\n`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.\n\n\u0026nbsp;\n\n## `toFixed()`\n\nThis 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**.\n\n- For precise calculations.\n\n- 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.\n\n  ```js\n  let num = 3.14159;\n  console.log(num.toFixed(2)); // \"3.14\"\n  ```\n\n- The `.toFixed()` method **rounds the number to the nearest value** that can be represented with the specified number of decimal places.\n\n  ```js\n  console.log((3.14159).toFixed(3));  // \"3.142\"\n  console.log((3.14449).toFixed(3));  // \"3.144\"\n  console.log((3.14550).toFixed(3));  // \"3.146\"\n  ```\n\n- if you call `.toFixed()` **without arguments**, it defaults to `0` decimal places.\n\n  ```js\n  let num = 3.14159;\n  console.log(num.toFixed()); // \"3\"\n  ```\n\n- The `.toFixed()` method can be particularly useful when working with **financial calculations** or displaying **prices**.\n\n  ```js\n  let price = 19.99;\n  let taxRate = 0.08;\n  let total = price + (price * taxRate);\n\n  console.log(\"Total: $\" + total.toFixed(2)); // \"Total: $21.59\"\n  ```\n\n\u0026nbsp;\n\n## Functions\n\nFunctions 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**.\n\n```js\nfunction greet() {\n  console.log(\"Hello, Jessica!\");\n}\n\ngreet(); // \"Hello, Jessica!\"\n```\n\n- **Parameters** act as **placeholders** for the values that will be passed to the function when it is called.\n\n  ```js\n  function greet(name) {\n    console.log(\"Hello, \" + name + \"!\");\n  }\n\n  greet(\"Alice\"); // Hello, Alice!\n  greet(\"Nick\"); // Hello, Nick!\n  ```\n\n- When a function finishes execution, it will always **return a value**. By default, the return value will be `undefined`. \n\n  ```js\n  function doSomething() {\n    console.log(\"Doing something...\");\n  }\n\n  let result = doSomething();\n  console.log(result); // undefined\n  ```\n\n- if you need your function to return a specific value, then you will need to use the `return` statement.\n\n  ```js\n  function calculateSum(num1, num2) {\n    return num1 + num2;\n  }\n\n  console.log(calculateSum(3, 4)); // 7\n  ```\n\n### Default Parameters\n\nFunctions support default parameters, allowing you to **set default values for parameters**. \n\n```js\nfunction greetings(name = \"Guest\") {\n  console.log(\"Hello, \" + name + \"!\");\n}\n\ngreetings(); // Hello, Guest!\ngreetings(\"Anna\"); // Hello, Anna!\n```\n\n\u0026nbsp;\n\n## Anonymous Function\n\nAn anonymous function is a function **without a name** that can be **assigned to a variable**.\n\n```js\nconst sum = function (num1, num2) {\n  return num1 + num2;\n};\n\nconsole.log(sum(3, 4)); // 7\n```\n\n\u0026nbsp;\n\n## Arrow Function Expression\n\n```js\nconst greetings = (name) =\u003e {\n  console.log(\"Hello, \" + name + \"!\");\n};\n```\n\n- if your parameter list only has **one** parameter in it, then you can **remove** the parentheses.\n\n  ```js\n  const greetings = name =\u003e {\n    console.log(\"Hello, \" + name + \"!\");\n  };\n  ```\n\n- But if your arrow function has **no** parameters, then you **must use the parentheses**. \n\n  ```js\n  const greetings = () =\u003e {\n    console.log(\"Hello\");\n  };\n  ```\n\n- And if your function body only contains only a **single line of code**, you can **remove** the curly braces.\n\n  ```js\n  const greetings = name =\u003e console.log(\"Hello, \" + name + \"!\");\n  ```\n\n  - if you're using `return` inside the function, you **must use the curly braces**.\n\n    ```js\n    const calculateArea = (width, height) =\u003e {\n      return width * height;\n    }; \n\n    console.log(calculateArea(5, 3)); // 15\n    ```\n\n  - Even if you **remove** that `return` statement, the function will still **implicitly `return`** the calculation.\n\n    ```js\n    const calculateArea = (width, height) =\u003e width * height;\n    ```\n\n\u0026nbsp;\n\n## Scope\n\nScope 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.\n\n### Global Scope\n\nit 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**.\n\n```js\nlet globalVar = \"I'm a global variable\";\n\nfunction printGlobalVar() {\n    console.log(globalVar);\n}\n\nprintGlobalVar(); // \"I'm a global variable\"\n```\n\n- While global variables should be used **sparingly**, as they can lead to **naming conflicts** and make your code **harder to maintain**. \n\n### Local Scope\n\nit refers to variables that are **only accessible within a function**. \n\n```js\nfunction greet() {\n    let message = \"Hello, local scope!\";\n    console.log(message);\n}\n\ngreet(); // \"Hello, local scope!\"\n// console.log(message); // This will throw an error\n```\n\n- Local variables help to keep different parts of your code **isolated**, which is especially useful in larger programs.\n\n### Block Scope\n\nA block is any code section **within** curly braces, `{}`, such as in `if` statements, `for` loops, or `while` loops. \n\n```js\nif (true) {\n    let blockVar = \"I'm in a block\";\n    console.log(blockVar); // \"I'm in a block\"\n}\nconsole.log(blockVar); // This will throw an error\n```\n\n- Block scope is a concept introduced with the **let** and **const** keywords in **ES6**.\n\n- Block scoping provides even **finer control** over variable accessibility, helping to prevent errors and make your code **more predictable**.\n\n\u0026nbsp;\n\n## \n\n\n\n\n\n\n\n\n\n\n\u0026nbsp;\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskywalkersam%2Fjs-101","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskywalkersam%2Fjs-101","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskywalkersam%2Fjs-101/lists"}