# 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 |