# javascript
## Resources
- [[#Learning Path]]
- [Algorithms](https://github.com/trekhleb/javascript-algorithms)
- [unminify code](https://unminify.com/)
## arrays
### destructuring
```js
// Before:
var width = 200;
var height = 400;
// After:
let [width, height] = [200, 400];
// before:
const calculateArea = (areaParameters) => areaParameters[0] * areaParameters[1]
calculateArea([200, 400]);
// or for better naming in older functions:
const calculateArea = ([width, height]) => width * height
calculateArea([200, 400]);
```
### every
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### Every method
this method returns a boolean value and is great for asking a question of your data and getting simple response in return. where as `some` just returns true as soon as it finds a single positive case, `every` reviews every value and only returns its result after every value has passed its check.
---
```js
const hasExpensiveItems = items.every((item) => {
return item.price <= 100
})
```
**Result:**
> false
for each item in items, iare all items less than or equal to 100? if so return true, otherwise false.
### filter
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### Filtering items
```js
const filteredItems = items.filter((item) => {
return item.price <= 100
})
console.log(filteredItems)
```
**Result:**
> .
> (3) ["Video 1 Recorded", "Video 2 Recorded", "Video 3 Recorded"]
> 0: "Video 1 Recorded"
> 1: "Video 2 Recorded"
> 2: "Video 3 Recorded"
> length: 3
> **proto**: Array(0)
Reading this like English,
- The immutable variable `filteredItems` receives the following value(s).
- The array of objects has the filter method applied
- The filter uses an arrow function #2 that takes a single parameter `(item)`
- The arrow function says "for each item in items, pass each item into my function body and operate upon it"
- Inside the function body the items price attribute is operated on with basic arithmetic to determine if it meets the condition `<=`
- If true, the data is returned with all other valid data that met the condition as the `.filter` method is an array method and likely returns an array as a result
- Each item that met the condition is then added to the resulting returned array
- The returned array is then assigned to the constant variable `filteredItems`
### foreach
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### For Each
does not return anything, basically acts like a for loop and takes a function as an argument as what you will be doing with each value
> "for each item in items, do the thing"
```js
items.forEach((item) => {
console.log(item.name)
})
```
**Result:**
Reading like English:
- for each item in the array object, pass it to the arrow function #2
- for each item i receive, log it
- next item
no returned objects just pure action
### includes
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### Includes Method
When you have a simple array and you just want to find out where a value is contained within it. Simple question, simple answer.
---
```js
const items = [1, 2, 3, 4, 5]
const includesTwo = items.includes(2)
console.log(includesTwo)
```
**Result:**
> true
### map
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### Map
Map will let you take an array and turn it into an entirely new array while also allowing you to perform operations upon it
---
```js
const itemPrice = items.map((item) => {
return item.price + 100
})
```
in other languages map always reminded me of applying a function to each item in an array/vector so in this case it is
- take each item in items
- pass to arrow functions (the surgical table)
- operate upon it (add 100 to the item)
- build the return array
- assign the return array to the `itemPrices` constant which consists of the original array with each element having had its prices increased by 100
### prototype includes
#### JavaScript Array.prototype.includes
ECMAScript 2016 introduced `Array.prototype.includes` to arrays. This allows us to check if an element is present in an array:
##### Example
```js
const fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.includes("Mango"); // is true
```
### reduce
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### Reduce method
This is like wanting to get a sum of all the prices of your items that meet certain conditions.
Unlike the other methods the `reduce` method has 2 arguments and the first of which has to be the aggregate value holder
---
```javascript
const total = items.reduce((currentTotal, item) => {
return item.price + currentTotal
}, 0)
console.log(total)
```
**Result:**
> 1840
we want to get a sum of all prices so we run the array method and for each item in items we pass the item and a local variable in the arrow function to the function body.
at then end of the arrow function is a second argument for the `reduce` method which is where the `currentTotal` value should start. We probably want a total to start at 0 so that's where it is set to.
this is like a for loop using `item = item + newItem`
so for each item passed to the function body, you also have the current running total passed as well. The items iteratively get returned and added to the `currentTotal` and then ultimately the `currentTotal` variable is returned giving you the sum of the array object's prices
### some
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/R8rmfD9Y5-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Given data:
```javascript
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
```
#### Some method
this method returns a boolean value and is great for asking a question of your data and getting simple response in return.
---
```javascript
const hasInexpensiveItems = items.some((item) => {
return item.price <= 100
})
```
**Result:**
> true
for each item in items, is there at least 1 item that is less than or equal to 100? if so return true, otherwise false.
## arrow functions
Arrow functions do not have their own `this`. They are not well suited for defining **object methods**.
Arrow functions are not hoisted. They must be defined **before** they are used.
Using `const` is safer than using `var`, because a function expression is always a constant value.
You can only omit the `return` keyword and the curly brackets if the function is a single statement. Because of this, it might be a good habit to always keep them:
```javascript
/*
Source: https://youtu.be/h33Srr5J9nY?list=PLZlA0Gpn_vH-0FlQnruw2rd1HuiYJHHkm
*/
// Normal function
function sum(a, b) {
return a + b
}
// if it can fit on 1 line these make the code more concise and legible
let sum2 = (a, b) => a + b
/**************************************************************************************/
function isPositive(number) {
return number >= 0
}
// Single parameter functions dont need parens on their args
let isPositive = number => number >= 0
/**************************************************************************************/
function randomNumber() {
return Math.random
}
// No parameter functions need the parens to exist though
let randomNumber = () => Math.random
/**************************************************************************************/
// arrow functions really useful for anonymous functions
document.addEventListener('click', function(){
console.log('click')
})
// is exactly the same as
document.addEventListener('click', () => console.log('click'))
/**************************************************************************************/
/*
The real power of arrow functions is the redeffinition of the the 'this' keyword
within them
*/
class Person {
constructor(name) {
this.name = name
}
printNameArrow() {
setTimeout(() => {
console.log('Arrow: ' + this.name)
}, 100)
}
printNameFunction() {
setTimeout(function() {
console.log('Arrow: ' + this.name)
}, 100)
}
}
let person = new Person('Bob')
person.printNameArrow() // acts like most other programming langs
person.printNameFunction() // prints nothing because in normal functions the 'this' is defined based on WHERE the function is called
console.log(this.name) // also returns nothing as 'this' is not defined in the global scope
/*
Normal functions redefine 'this' to what ever scope you function in and that is the global scope in this instance
Arrow functions treat the scoping of the 'this' keyword like most other programming language now
its preferable now to use arrow function over normal functions unless explicitly necessary to use normal functions
*/
```
### Default Parameter Values
```js
function myFunction(x, y = 10) {
// y is 10 if not passed or undefined
return x + y;
}
myFunction(5); // will return 15
```
## Async and Defer
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/BMuFBYw91UQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</center>
Normal DOC parsing is that is parses synchronously, so as soon as it hits a `<script>` tag it stops and downloads that content first and then executes it and only THEN continues with the HTML download/parsing.
### Async
with `Async` the downloads happen concurrently and only the Javascript execution is treat synchronously
![[95397297-b4c85f80-08b7-11eb-8a63-068446b52032.png]]
`Async` will allow the javascript to also run after the document `onReady()` event maybe this is not what you want. `Async` will also vary when it is run as it can be variable based on network speeds. if order matters this will throw a wrench in the works as it can be executed whenever dependent on the users network conditions.
### Defer
with defer it will defer javascript execution until all the parsing is done, this way all the content is loaded and prepared before javascript begins to act upon them
![[95397383-e9d4b200-08b7-11eb-9075-2acd110eb0a1.png]]
defer will run your deferred code before the document `onReady()` event. and it will stay in order and run when the page is done being parsed.
To imitate the behavior of `defer` people commonly put their script tags in the end of the `</body>` tag, with the `defer` keyword now though we can put the javascript files back in the `<head>` so they are easier to find but still have the same behavior as leaving them at the bottom.
---
Defer is more reliable as it is ordered and you know when it will run. Async can be useful if you have small files that don't depend on anything that you want to have loaded whenever.
---
```html
// Normal
<script src="file.js"></script>
// Async
<script async src="file.js"></script>
// Defer
<script defer src="file.js"></script>
```
## classes
JavaScript Classes are templates for JavaScript Objects.
Use the keyword `class` to create a class.
Always add a method named `constructor()`:
```js
class Car
{
constructor(name, year)
{
this.name \= name;
this.year \= year;
}
}
```
A JavaScript class is **not** an object.
It is a **template** for JavaScript objects.
```js
let myCar1 = new Car("Ford", 2014);
let myCar2 = new Car("Audi", 2019);
```
## conditional-logic-and-control-flow
### Resources
- <https://levelup.gitconnected.com/how-you-can-avoid-using-else-in-your-code-871197a1adbc>
- <https://www.w3schools.com/Js/js_json.asp>
### Efficient Usage
The most classic form of the if-else statement looks really simple.
```js
if (someCondition) {
// 10 lines of code
} else {
// More code..
}
```
This is how we could use a return in order to get rid of the else block:
```js
if (someCondition) {
// 10 lines of code
return;
}
// More code..
```
If-else statements get used a lot to assign variables
```js
if (someCondition) {
number = someNumber * 2
} else {
number = 1
}
```
When you spot code like this, change it. The way to get rid of the else block is by assigning a default value.
```js
number = 1
if (someCondition) {
number = someNumber * 2
}
```
There’s a way to optimize this code even more. We could make this piece of code a one-liner by using the conditional operator:
```js
number = someCondition ? someNumber * 2 : 1;
```
[[Guard Clauses]] are also known as early-returns.
## dom manipulation
The way of accessing the DOM tree.
| | |
| --- | --------------------------- |
| DOM | `D`ocument `O`bject `M`odel |
---
- Reference:
- <https://developer.mozilla.org/en-US/docs/Web/API/Document>
### queryselector
returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, `null` is returned.
#### Finding the first element matching a class
In this example, the first element in the document with the class "`myclass`" is returned:
```javascript
var el = document.querySelector(".myclass");
```
#### A more complex selector
Selectors can also be really powerful, as demonstrated in the following example. Here, the first `<input>` element with the name "_login_" (`<input name="login"/>`) located inside a `<div>` whose class is "user-panel main" (`<div class="user-panel main">`) in the document is returned:
```javascript
var el = document.querySelector("div.user-panel.main input[name='login']");
```
#### Negation
As all CSS selector strings are valid, you can also negate selectors:
```javascript
var el = document.querySelector("div.user-panel:not(.main) input[name='login']");
```
This will select an input with a parent div with the user-panel class but not the main class.
---
- Reference:
- [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
## es6
### array methods
#### find
##### Array.find()
The `find()` method returns the **value** of the first array element that passes a test function.
This example finds (returns the value of ) the first element that is larger than 18:
###### Example
```js
var numbers = [4, 9, 16, 25, 29];
var first = numbers.find(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
myFunction(25,3,numbers); // TRUE
```
```js
const items = [
{ name: 'Bike', price: 100 },
{ name: 'TV', price: 200 },
{ name: 'Album', price: 10 },
{ name: 'Book', price: 5 },
{ name: 'Phone', price: 500 },
{ name: 'Computer', price: 1000 },
{ name: 'Keyboard', price: 25 }
]
const foundItem = items.find((item) => {
return item.name === 'Book'
})
console.log(foundItem)
```
> {name: "Book", price: 5}
>
> name: "Book"
>
> price: 5
>
> **proto**: Object
>
#### findindex
##### Array.findIndex()
The `findIndex()` method returns the **index** of the first array element that passes a test function.
This example finds the index of the first element that is larger than 18:
###### Example
```js
var numbers = [4, 9, 16, 25, 29];
var first = numbers.findIndex(myFunction);
function myFunction(value, index, array) {
return value > 18;
}
myFunction(25,3,numbers);
```
### numbers
#### The isFinite() Method
The global `isFinite()` method returns `false` if the argument is `Infinity` or `NaN`.
Otherwise it returns `true`:
##### Example
```js
isFinite(10/0); // returns false
isFinite(10/1); // returns true
```
[Try it Yourself »](https://www.w3schools.com/Js/tryit.asp?filename=tryjs_es6_isfinite)
#### The Number.isInteger() Method
The `Number.isInteger()` method returns `true` if the argument is an integer.
##### Example
```js
Number.isInteger(10); // returns true
Number.isInteger(10.5); // returns false
```
#### The isNaN() Method
The global `isNaN()` method returns `true` if the argument is `NaN`. Otherwise it returns `false`:
##### Example
```js
isNaN("Hello"); // returns true
```
#### The Number.isSafeInteger() Method
A safe integer is an integer that can be exactly represented as a _double precision number_.
The `Number.isSafeInteger()` method returns `true` if the argument is a safe integer.
##### Example
```js
Number.isSafeInteger(10); // returns true
Number.isSafeInteger(12345678901234567890); // returns false
```
Safe integers are all integers from
**$-(2^{53} - 1)$** to **$+(2^{53} - 1)$**
This is safe: _9007199254740991_
This is not safe: _9007199254740992_
#### New Number Properties
ES6 added the following properties to the Number object:
- `EPSILON`
- `MIN_SAFE_INTEGER`
- `MAX_SAFE_INTEGER`
```js
var x = Number.EPSILON;
console.log(x);
// 2.220446049250313e-16
var x = Number.MIN_SAFE_INTEGER;
console.log(x);
// 4 -9007199254740991
var x = Number.MAX_SAFE_INTEGER;
console.log(x);
// 6 9007199254740991
```
## event-listeners
`target.addEventListener( type, listener );`
[event types](https://developer.mozilla.org/en-US/docs/Web/Events)
the Listener is what receives notification. I.E. trigger the event type, then activate the listener code. So if the listener is an [[JavaScript Arrow Functions|arrow-function]] then you can run an entire anonymous function.
### Click event
<https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event>
## exponentation
```js
let base = 3;
let exponent = 4;
// old way Math.pow()
console.log(Math.pow(base ,exponent)) //81
// new way
console.log(base**exponent); //81
```
### Exponentiation Assignment
The **exponentiation assignment** operator (`**=`) raises the value of a variable to the power of the right operand.
#### Example
```js
let x = 5;
x **= 2; // result 25
```
## The `for...of` Loop
The new `for...of` loop allows us to iterate over arrays or other iterable objects very easily.
Also, the code inside the loop is executed for each element of the iterable object. Here's an example:
```js
// Iterating over array
let letters = ["a", "b", "c", "d", "e", "f"];
for(let letter of letters) {
console.log(letter); // a,b,c,d,e,f
}
// Iterating over string
let greet = "Hello World!";
for(let character of greet) {
console.log(character); // H,e,l,l,o, ,W,o,r,l,d,!
}
```
---
- Reference:
- <https://www.tutorialrepublic.com/javascript-tutorial/javascript-es6-features.php>
## function rest parameter
### The Rest Parameters
This is similar to the function ellipsis parameter in [[DevLog/r|r]] where the number of inputs in variable and you want to accept them all as a variable size [[Python Data Structures|python-data-structures#List]]/Array.
The rest parameter (`...`) allows a function to treat an indefinite number of arguments as an array:
```js
function sum(...args) {
let sum = 0;
for (let arg of args) sum += arg;
return sum;
}
let x = sum(4, 9, 16, 25, 29, 100, 66, 77);
```
### The Spread Operator
The spread operator, which is also denoted by (`...`), performs the exact opposite function of the rest operator. The spread operator spreads out (i.e. splits up) an array and passes the values into the specified function, as shown in the following example:
```js
function addNumbers(a, b, c) {
return a + b + c;
}
let numbers = [5, 12, 8];
// ES5 way of passing array as an argument of a function
document.write(addNumbers.apply(null, numbers)); // 25
document.write("<br>");
// ES6 spread operator
document.write(addNumbers(...numbers)); // 25
```
The spread operator can also be used to insert the elements of an array into another array without using the array methods like `push()`, `unshift()` `concat()`, etc.
```js
let pets = ["Cat", "Dog", "Parrot"];
let bugs = ["Ant", "Bee"];
// Creating an array by inserting elements from other arrays
let animals = [...pets, "Tiger", "Wolf", "Zebra", ...bugs];
document.write(animals); // Cat,Dog,Parrot,Tiger,Wolf,Zebra,Ant,Bee
```
## Learning Path
![[Web_Development_2021_Roadmap.pdf]]
### How the internet works
❌️ <https://www.youtube.com/watch?v=7_LPdttKXPc>
❌️ <https://www.youtube.com/watch?v=Dxcc6ycZ73M>
❌️ Hosting
❌️ [[DNS]]
❌️ HTTP
❌️ Browsers
❌️ Domain Names
### Basic Tools
#### Text Editor
❌️ <https://www.youtube.com/playlist?list=PLkwxH9e_vrAJshxiMo6gIavTr5kYsjPs7>
❌️ <https://vscodehero.com/>
#### Design
❌️ <https://www.youtube.com/channel/UCVyRiMvfUNMA1UPlDPzG5Ow>
❌️ <https://www.youtube.com/channel/UCvM5YYWwfLwpcQgbRr68JLQ>
### HTML
❌️ <https://www.youtube.com/watch?v=XiQ9rjaa2Ow>
❌️ Best Practices
❌️ Semantic HTML
❌️ Forms and Validations
❌️ Accessibility
❌️ SEO
### CSS
❌️ [Basics](https://www.youtube.com/watch?v=Tfjd5yzCaxk)
❌️ _pros and cons of these_
❌️ [flexbox](https://www.youtube.com/watch?v=qqDH0T6K5gY)
❌️ [css grid](https://www.youtube.com/watch?v=BDOzg4lXcSg)
❌️ custom properties
#### transitions/animations
❌️ plain CSS
❌️ [GSAP](https://greensock.com/gsap/) and [GSAP typing animation](https://www.youtube.com/watch?v=ZT66N5hBiCE)
❌️ [anime.js](https://animejs.com/)
#### Responsive Design
❌️ Mobile first
❌️ rem units
❌️ viewport
❌️ fluid widths
❌️ media queries
❌️ [kevin powell](https://www.youtube.com/channel/UCJZv4d5rbIKd4QHMPkcABCw)
#### CSS Preprocessorts
❌️ [SASS](https://www.youtube.com/watch?v=BDOzg4lXcSg)
❌️ postCSS
#### Modern CSS
❌️ [styled components](https://styled-components.com/)
❌️ [CSS Modules](https://github.com/css-modules/css-modules)
#### CSS Prameworks
❌️ [tailwind CSS](https://tailwindcss.com/)
❌️ [bootstrap](https://getbootstrap.com/)
### Paths
#### Desktop Applications
❌️ Electron
#### Mobile Apps
❌️ React Native
❌️ <https://www.youtube.com/channel/UC806fwFWpiLQV5y-qifzHnA>
❌️ Flutter
❌️ <https://www.youtube.com/user/Lionranger>
❌️ <https://www.youtube.com/c/TadasPetra>
❌️ <https://www.youtube.com/c/RobertBrunhage/>
❌️ NativeScript
❌️ Ionic
#### front end
##### Javascript
❌️ [Basic Syntax ](https://www.youtube.com/watch?v=d5ob3WAGeZE)
❌️ DOM Manipulation
❌️ [Fetch API](https://www.youtube.com/watch?v=djCuFrLLjVk)
❌️ [JSON](https://www.youtube.com/watch?v=s6OIOL9OMYA)
❌️ ES6+
❌️ <https://www.youtube.com/playlist?list=PLkwxH9e_vrALRJKu7wfXby3MKeflhTu6B>
❌️ <https://www.youtube.com/watch?v=bGDK1rpykOQ&list=PLkwxH9e_vrALlH7D0XLDn2td-uoHqHFxq>
❌️ [typescript](https://www.youtube.com/watch?v=ahCwqrYpIuM)
###### More Tools
❌️ Browser dev tools
❌️ [VSCode extentions](https://www.youtube.com/watch?v=c5GAS_PMXDs)
❌️ [emmet](https://www.youtube.com/watch?v=EzGWXTASWWo)
❌️ [[HTML Emmet Shortcuts in VSCode|html-emmet-shortcuts-in-vscode]]
❌️ [axios](https://www.youtube.com/watch?v=6LyagkoRWYA)
###### version control
❌️ [git](https://www.youtube.com/watch?v=N_bMCff8q6A)
- [x] github
###### Build Tools
❌️ **Task Runners**
❌️ NPM Scripts
❌️ [GULP](https://www.youtube.com/watch?v=-lG0kDeuSJk)
❌️ **Linters / Formatters**
❌️ [Prettier](https://prettier.io/)
❌️ [ESLint](https://eslint.org/)
❌️ **Module Bundlers**
❌️ [webpack](https://www.youtube.com/watch?v=MpGLUVbqoYQ)
❌️ [parcel](https://www.youtube.com/watch?v=ONwotPEpinI)
❌️ [Rollup](https://rollupjs.org/guide/en/)
###### Preogressive web apps
❌️ [PWA's](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gTxqJBcDmoi5Q2pzDusSL7)
❌️ <https://www.youtube.com/watch?v=ppwagkhrZJs>
###### Graph-QL
❌️ [Apollo](https://www.youtube.com/watch?v=ed8SzALpx1Q)
###### Package Managers
❌️ [NPM](https://nodejs.org/en/)
❌️ [yarn](https://classic.yarnpkg.com/en/docs/install)
###### Jam Stack
❌️ Javascript
❌️ <https://www.youtube.com/watch?v=ySJGjo3_EX4>
❌️ <https://www.youtube.com/watch?v=73b1ZbmB96I>
❌️ [API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API)
❌️ Markup
###### Front End Framework
❌️ [React](https://www.youtube.com/watch?v=UGcALH8kPC0&list=PLkwxH9e_vrAK4TdffpxKY3QGyHCpxFcQ0)
❌️ Vue
❌️ <https://www.youtube.com/channel/UCshZ3rdoCLjDYuTR_RBubzw>
❌️ <https://www.youtube.com/channel/UCxA99Yr6P_tZF9_BgtMGAWA>
###### State Management
❌️ [Context API (React)](https://www.youtube.com/watch?v=35lXWvCuM8o)
❌️ [Redux (React)](https://www.youtube.com/watch?v=CVpUuw9XSjY)
❌️ [Vuex (Vue)](https://www.youtube.com/watch?v=oxUyIzDbZts)
###### Server Side Rendering (SSR)
❌️ [Nuxt.js (Vue)](https://www.youtube.com/watch?v=ltzlhAxJr74)
❌️ [Next.js (React)](https://www.youtube.com/channel/UC7Wpv0Aft4NPNhHWW_JC4GQ)
###### Static Site Generators
❌️ [Gatsby (React)](https://www.youtube.com/user/Weibenfalk)
❌️ Next.js (React)
❌️ [Gridsome (Vue)](https://www.youtube.com/watch?v=vB6rmWCmANA)
❌️ Nuxt.js (Vue)
❌️ 11ty
## Modules
Prior to ES6, there were no native support for modules in JavaScript. Everything inside a JavaScript application, for example variables across different JavaScript files, shared the same scope.
ES6 introduces file based module, in which each module is represented by a separate `.js` file. Now, you can use the `export` or `import` statement in a module to export or import variables, functions, classes or any other entity to/from other modules or files.
This works in conjunction with [[JavaScript Variable Assignment|s.l.javascript.variable-assignment]] options that came with ES6 to constrain variables to local scopes and not a global scope as well.
Let's create a module i.e. a JavaScript file "`main.js`" and place the following code in it:
```js
let greet = "Hello World!";
const PI = 3.14;
function multiplyNumbers(a, b) {
return a \* b;
}
// Exporting variables and functions
export { greet, PI, multiplyNumbers };
```
Now create another JavaScript file "app.js" with the following code:
```js
import { greet, PI, multiplyNumbers } from './main.js';
alert(greet);
// Hello World!
alert(PI);
// 3.14
alert(multiplyNumbers(6, 15)); // 90
```
### Changing the names of the default import
so if you have a User [[JavaScript Classes|class]] you're importing but in the new file you import that into you want to import that class but call it something different, then what you can do is basically treat it like a base class (which it is) and say:
`import U from '/user.js'`
because the User class is the default export its assuming we're saying something like this if we were in python
```python
import pandas as pd
```
except that its `import User as U`
### default-imports
#### You can only default export one thing so it will likely be the class you are defining if you are defining a class in your file
Now in a new file we can `import` your `exported` items paying attention to your file paths in the import statements
`import User from '/user.js'`
this alone will throw an error, in your HTML where you source your javascript files you need to change the `script` tag to use ES6 modules:
`<script src="main.js"></script>`
`<script type="module" src="main.js"></script>`
a tip for the module import `<script>` tag was the `defer` keyword. Child issue: #6
so now in a `*.js` file that does not have the User class declared in it, i can make and use the User class:
```js
const user = new User('Bryan Jenks', 999)
console.log('user')
```
**Result:**
> User {name: "Bryan Jenks", age: 999}
> age: 999
> name: "Bryan Jenks"
> **proto**: Object
### ES6 Modules
[source](https://youtu.be/cRHQNNcYf6s?list=PLZlA0Gpn_vH-0FlQnruw2rd1HuiYJHHkm)
Importing sections of code so that files can be broken out into more modular files
---
2 types of exports, the default is the following at the end of a file:
`export default User`
this exports the User object as our default thing for the user.js file
the normal way of exports is:
`export { printName, printAge }`
which will export those two functions
an even better way would be inline like the example below for both the `User` class and functions:
```javascript
export default class User {
constructor(name, age) {
this.name = name
this.age = age
}
}
export function printName(user) {
console.log(`User's name is ${user.name}`)
}
export function printAge(user) {
console.log(`User's is ${user.age} years old`)
}
```
Finally create a HTML file "`test.html`" and with the following code and open this HTML file in your browser using HTTP protocol (or use localhost). Also notice the `type="module"` on script tag.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JavaScript ES6 Modules Demo</title>
</head>
<body>
<script type="module" src="/examples/js/app.js"></script>
</body>
</html>
```
### [[s.l.javascript.releases.ecmascript-2020]]
#### Hot loading modules
```js
const baseModulePath = "./modules";
const btnBooks = document.getElementById("btnBooks");
let bookList = [];
btnBooks.addEventListener("click", async e => {
const bookModule = await import(`${baseModulePath}/books.js`);
bookList = bookModule.loadList();
});
```
So this code will only load the module on a particular click event, instead of a static declaration at the top of a file.
### To import non-default things
if we want the functions we defined in the `user.js` file and also exported, we can also import them with the following syntax:
```js
import U, { printName, printAge } from '/user.js'
```
basically, the default import can just be declared as `U` in this instance, where as non default imports have to be imported with the brace syntax. We can also change the name of those items too in this following was:
```js
import U, { printName as printUsername, printAge as printUserAge } from '/user.js'
```
For more browser support a common method of dealing with imports is to use the `babel` tool to convert these newer features into older and supported javascript code
## The object destructuring assignment
In ES5 to extract the property values of an object we need to write something like this:
```js
// ES5 syntax
var person = {name: "Peter", age: 28};
var name = person.name;
var age = person.age;
document.write(name); // Peter
document.write("<br>");
document.write(age); // 28
```
But in ES6, you can extract object's property values and assign them to the variables easily like this:
```js
// ES6 syntax
let person = {name: "Peter", age: 28};
let {name, age} = person; // Object destructuring assignment
document.write(name); // Peter
document.write("<br>");
document.write(age); // 28
```
---
- Reference:
- <https://www.tutorialrepublic.com/javascript-tutorial/javascript-es6-features.php>
## JavaScript Object Entries
ECMAScript 2017 adds a new `Object.entries` method to objects:
### Example
```js
const person = {
firstName : "John",
lastName : "Doe",
age : 50,
eyeColor : "blue"
};
document.getElementById("demo").innerHTML = Object.entries(person);
```
## JavaScript Object Values
`Object.values` are similar to `Object.entries`, but returns a single dimension array of the object values:
### Example
```js
const person = {
firstName : "John",
lastName : "Doe",
age : 50,
eyeColor : "blue"
};
document.getElementById("demo").innerHTML = Object.values(person);
```
## Promises
> "Im going to give you the best video on promises"
---
```js
let p = new Promise((resolve, reject) => {
let a = 1 + 1
if (a == 2) {
resolve('Success')
} else {
reject('Failed')
}
})
```
1+1 will always = 2 so the `resolve()` method is called.
so if the promise is going to be resolved and we keep our promise of delivering a great video, **THEN** we resolve the promise.
this is also basically a try catch block but without the finally
```js
p.then((message) => {
console.log('This is in the then' + message)
}).catch((message) => {
console.log('This is in the catch' + message)
})
```
Promises are things you want to happen in the background but that take a long time.
like downloading an image in a server and not making other things wait for it.
---
### Batching Promise Execution
```js
const recordVideoOne = new Promise((resolve, reject) => {
resolve('Video 1 Recorded')
})
const recordVideoTwo = new Promise((resolve, reject) => {
resolve('Video 2 Recorded')
})
const recordVideoThree = new Promise((resolve, reject) => {
resolve('Video 3 Recorded')
})
```
run a bunch of promises all at once in parallel instead of sequentially.
these promises all resolve and dont reject.
```js
Promise.all([
recordVideoOne,
recordVideoTwo,
recordVideoThree
]).then((messages) => {
console.log(messages)
})
```
so once the promises resolve the `.then` will then return an array of messages from the promises that we can then log
### Callbacks (superceded by promises)
```js
const userLeft = false
const userWatchingCatMeme = false
function watchTutorialCallback(callback, errorCallback) {
if (userLeft) {
errorCallback({
name: 'User Left',
message: ':('
})
} else if (userWatchingCatMeme) {
errorCallback({
name: 'User Watching Cat Meme',
message: 'WebDevSimplified < Cat'
})
} else {
callback('Thumbs up and Subscribe')
}
}
watchTutorialCallback((message) => {
console.log('Success ' + message)
}, (error) => {
console.log(error.name + ' ' + error.message)
}
```
Promises were meant to supercede callbacks and now the same code can be put into a promise:
```js
function watchTutorialPromise() {
return new Promise((resolve, reject) => {
if (userLeft) {
reject({
name: 'User Left',
message: ':('
})
} else if (userWatchingCatMeme) {
reject({
name: 'User Watching Cat Meme',
message: 'WebDevSimplified < Cat'
})
} else {
resolve('Thumbs up and Subscribe')
}
})
}
watchTutorialPromise.then((message) => {
console.log('Success ' + message)
}).catch((error) => {
console.log(error.name + ' ' + error.message)
})
```
The code looks cleaner and to avoid lots of nested callbacks and "callback hell" you can just use this syntax to deal with multiple then actions
```js
watchTutorialPromise.then((message) => {
console.log('Success ' + message)
}).then((message) => {
console.log('Success ' + message)
}).catch((error) => {
console.log(error.name + ' ' + error.message)
})
```
### Return the Quickest Completed item
`promise.all` waits for all of the promises to finish execution before returning results
where as
`promise.race` returns as soon as anything finishes and will return that first completed item in the `.then` so that an array isnt returned only a single result value of the quickest item because its a `.race`
```js
Promise.race([
recordVideoOne,
recordVideoTwo,
recordVideoThree
]).then((message) => {
console.log(message)
})
```
### Callbacks (superceded by promises)
```js
const userLeft = false
const userWatchingCatMeme = false
function watchTutorialCallback(callback, errorCallback) {
if (userLeft) {
errorCallback({
name: 'User Left',
message: ':('
})
} else if (userWatchingCatMeme) {
errorCallback({
name: 'User Watching Cat Meme',
message: 'WebDevSimplified < Cat'
})
} else {
callback('Thumbs up and Subscribe')
}
}
watchTutorialCallback((message) => {
console.log('Success ' + message)
}, (error) => {
console.log(error.name + ' ' + error.message)
}
```
Promises were meant to supercede callbacks and now the same code can be put into a promise:
```js
function watchTutorialPromise() {
return new Promise((resolve, reject) => {
if (userLeft) {
reject({
name: 'User Left',
message: ':('
})
} else if (userWatchingCatMeme) {
reject({
name: 'User Watching Cat Meme',
message: 'WebDevSimplified < Cat'
})
} else {
resolve('Thumbs up and Subscribe')
}
})
}
watchTutorialPromise.then((message) => {
console.log('Success ' + message)
}).catch((error) => {
console.log(error.name + ' ' + error.message)
})
```
The code looks cleaner and to avoid lots of nested callbacks and "callback hell" you can just use this syntax to deal with multiple then actions
```js
watchTutorialPromise.then((message) => {
console.log('Success ' + message)
}).then((message) => {
console.log('Success ' + message)
}).catch((error) => {
console.log(error.name + ' ' + error.message)
})
```
## Promises
> "Im going to give you the best video on promises"
---
```js
let p = new Promise((resolve, reject) => {
let a = 1 + 1
if (a == 2) {
resolve('Success')
} else {
reject('Failed')
}
})
```
1+1 will always = 2 so the `resolve()` method is called.
so if the promise is going to be resolved and we keep our promise of delivering a great video, **THEN** we resolve the promise.
this is also basically a try catch block but without the finally
```js
p.then((message) => {
console.log('This is in the then' + message)
}).catch((message) => {
console.log('This is in the catch' + message)
})
```
Promises are things you want to happen in the background but that take a long time.
like downloading an image in a server and not making other things wait for it.
---
### Batching Promise Execution
```js
const recordVideoOne = new Promise((resolve, reject) => {
resolve('Video 1 Recorded')
})
const recordVideoTwo = new Promise((resolve, reject) => {
resolve('Video 2 Recorded')
})
const recordVideoThree = new Promise((resolve, reject) => {
resolve('Video 3 Recorded')
})
```
run a bunch of promises all at once in parallel instead of sequentially.
these promises all resolve and dont reject.
```js
Promise.all([
recordVideoOne,
recordVideoTwo,
recordVideoThree
]).then((messages) => {
console.log(messages)
})
```
so once the promises resolve the `.then` will then return an array of messages from the promises that we can then log
## releases
### ecmascript-2015
ECMAScript 6, also known as ES6 and ECMAScript 2015, was the second major revision to JavaScript.
List of `ES6` Changes:
- [[JavaScript Variable Assignment|variable-assignment]]
- [[JavaScript Arrow Functions|arrow-functions]]
- [[JavaScript Function Rest Parameter|function-rest-parameter]]
- [[JavaScript Classes|classes]]
- [[JavaScript Promises|promises]]
- [[JavaScript Symbol Type|symbol-type]]
- [[JavaScript Object Destructuring|object-destructuring]]
- [[JavaScript Array Destructuring|arrays.destructuring]]
- [[JavaScript For..of Loop|for-of-loop]]
- [[JavaScript Template Literals|template-literals]]
- [[JavaScript Modules|modules]]
### ecmascript-2016
- [[exponentation]]
- [[prototype-includes]]
### ecmascript-2017
- [[string-padding]]
- [[object-entries]]
- [[object-values]]
- [[async-and-defer]]
### ecmascript-2020
- modules
## JavaScript String Padding
ECMAScript 2017 added two String methods: `padStart` and `padEnd` to support padding at the beginning and at the end of a string.
### Example
```js
let str = "5";
str = str.padStart(4,0);
// result is 0005
//========================//
let str = "5";
str = str.padEnd(4,0);
// result is 5000
```
## symbol type
A JavaScript `Symbol` is a primitive datatype just like Number, String, or Boolean.
It represents a unique "_hidden_" identifier that no other code can accidentally access.
For instance, if different coders want to add a `person.id` property to a person object belonging to a third-party code, they could mix each others values.
Using `Symbol()` to create a unique identifiers, solves this problem:
```js
const person = {
firstName: "John",
lastName: "Doe",
age: 50,
eyeColor: "blue"
};
let id = Symbol('id');
person.id = 140353;
```
Symbols are always unique.
If you create two symbols with the same description they will have different values.
```js
Symbol("id") == Symbol("id") // false
```
## JavaScript String Padding
ECMAScript 2017 added two String methods: `padStart` and `padEnd` to support padding at the beginning and at the end of a string.
### Example
```js
let str = "5";
str = str.padStart(4,0);
// result is 0005
//========================//
let str = "5";
str = str.padEnd(4,0);
// result is 5000
```
## [[import.software.language.javascript.template-cloning]]
---
This is a method of a [[s.m.html.tags.body.template-tag]] element to copy the content of the template into a new variable for manipulation. Such as several new list items to be appended to a list.
## Template Literals
Template literals provide an easy and clean way create multi-line strings and perform string interpolation. Now we can embed variables or expressions into a string at any spot without any hassle.
Template literals are created using back-tick (`` ` ` ``) (grave accent) character instead of the usual double or single quotes. Variables or expressions can be placed inside the string using the `${...}` syntax. Compare the following examples and see how much useful it is:
```js
// Simple multi-line string
let str = `The quick brown fox
jumps over the lazy dog.`;
document.write(`<pre>${str}</pre>`);
// String with embedded variables and expression
let a = 10;
let b = 20;
let result = `The sum of ${a} and ${b} is ${a+b}.`;
document.write(result); // The sum of 10 and 20 is 30.
```
## the const keyword
The `CONST` keyword is a way to assign a value to an immutable variable that respects local scoping.
```js
var x = 10;
// Here x is 10
{
const x = 2;
// Here x is 2
x = 5;
// ERROR: value cannot be re-assigned
}
// Here x is 10
```
## the let keyword
The `let` keyword is a way to assign a value to a mutable variable that respects local scoping.
```js
var x = 10;
// Here x is 10
{
let x = 2;
// Here x is 2
}
// Here x is 10
```
## the var keyword
The `VAR` Keyword is a variable assignment declaration that is available globally in scope no matter where it is declared.
```js
var x = 10;
// Here x is 10
{
let x = 2;
// Here x is 2
}
// Here x is 10
```
## variable assignment
There are 3 methods of variable assignment in JavaScript
| Assignment Keyword | Scope | Mutable |
| --------------------------------------------------------- | ------ | ------- |
| [[the-var-keyword]] | global | Yes |
| [[the-let-keyword]] | local | Yes |
| [[the-const-keyword]] | local | No |