== is less strict. It converts numbers into strings if necessary.
= means it will become.
An empty string "" is a falsey value.
Expressions passed into conditions are translated into booleans.
if (const === 5){
//runs if const === 5 (truthy)
//ignores if const !==5 (falsey)
}
Arrays
Arrays are stored in [].
They start at 0.
To call an array item do arrayName[0 (for first item), 1, 2, 3, -1 (for last item)].
arrayName.length counts the number of items in an array, starting at one, which is why in a for (let i = 0; i < array.length; i++){}
i is less than not less then or equal to.
An array is a complex data type.
arrayName.push(newItem) adds content to the end of an array.
arrayName.pop() removes the last item of an array.
The i for loop, for (let i = 0; i < maxAmountOfLoop; i++){} will iterate through an array and represent each item as i. To get
i of the array, use arrayName[i]
If you need a element from function1 use a parameter in function2 and call function2 in function1.
function function1(){
const var1 = 'string';
function2(var1);
}
function function2(var){
var
}
Object
let objectName = { "key": "value" }
Turn an objects values into an array by using Object.values(objectName).
Turn an objects keys into an array by using Object.keys(objectName)
Turn an object into an array of arrays by using Object.entries(objectName)
Grabbing Elements
.append(element) adds the string or object to whatever you're appending to.
getElementbyID('id') will get a single element with the unique id you provided. If more than one element has that id (id's should be unique) it will get the
first it finds.
The querySelector('#id') is more dynamic. You have to be more specific and identify the element how you would in CSS
(with . or # before the name if applicable). It will return the first item with the parameter you entered. This is unique because it can grab psudo selectors.
getElementsbyClassName('class') will return an object-like array of all the child elements that have that class name.
The Dialog Tag
dialog.show() opens a non-modal dialog.
dialog.showModal() opens a modal.
dialog.close() closes the dialog.
To close the dialog when clicking outside the dialog box:
dialog.addEventListener("click", e=> {
const dialogDimentions = dialog.getBoundingClientRect()
if (
// clicking outside the dialog
clientX < dialogDimensions.left ||
e.clientX > dialogDimensions.right ||
e.clientY < dialogDimensions.top ||
e.clientY > dialogDimensions.bottom ||
// clicking the cancel button
e.target.id === "cancel-dialog-btn"
){
dialog.close()
}
})
setTimeout()
A method that delays the execution of the code inside it for the entered time.
setTimeout(function(){
what you don't want to fire
}, number of miliseconds you want to delay by)
To stop a timeout before it runs it's code you can use
const timer = setTimeout(functionName, 3000, 'param')
document.getElementById('stopBtn').addEventListener('click', function(){
clearTimeout(timer)
})
element.style
Targets an element's style.
elementName.style.what you want to change = "what you want to change it to"
elementName.style.display = 'none' to change the elements display to none, reguardless of entered CSS.
To override the form information being pushed into the URL query screen,
formElement.addEventListener('submit', function(event){
event.preventDefault();
})
Any button in a form will submit by default. To stop this change the type. type="reset, submit, button" to anything but submit.
Disabling Elements
Controlling when elements are usable.
To disable on page load add disabled to HTML tag.
<button disabled>
To disable after load, set disabled to true.
document.getElementById('id').disabled = true
Class List
element.classList.action('className') some actions are toggle, remove, and add.
Just element.classList will return the entire class list of the element.
element.classList.toggle('className')
switches the usage of the classlist back and forth.
element.classList.remove('className')
will remove className from the elements class list.
element.classList.add('className')
will add className to the elements class list.
for of
A nicer way of iterating.
for (let item of itemsObjArr) {
console.log(itemsObjArr[item])
}
Iterates over object data structures.
Iterates over the values of an iterable object. (examples of iterable objects include arrays, strings).
for in
for (let item in items){
console.log(items[item])
}
Iterates over object data structures.
iterates over all enumerable property keys of an object.
The Includes Method
A method for checking if an array holds a given value.
An easy method for beginners.
Returns a boolean.
arr.includes(value) would return true or false.
Get the event in an event listener
container.addEventListener('click', function(event){
console.log(event.target)
})
will log the event target, which is the entire tag.
If you log just event, you will see PointerEvent{ isTrusted: boolean } as the log.
The target will show the most exact location it can (p.className#idName).
An empty area in the container will return a string.
event.target.id would return just the id of what was clicked.
Adding .parentElement to the end of what your selecting (event.target.id).parentElement
will return the parent element of the element that had an event. So if this is the HTML
<div class="parent-element">
<div id="childElement"></div>
</div>
, then in the JS this
event.target.id.parentElement, if the child element is selected, it would return <div class="parent-element">.
Writing Big Numbers in JS
You can add a numeric seperator, _, between numbers in the code to make it more readable and it will display without it.
const longNumber = 9_007_199_254_740_991
console.log(longNumber)//returns 9007199254740991
console.log(typeof longNumber)//returns number
9007199254740991 is the highest number js can calculate without losing precision.
For numbers bigger than 9007199254740991 you can use BigInt().
const longerNumber = 9007199254740991345n
console.log(typeof longerNumber) // returns bigint, not number
.
BigInt() is a constructor.
const longerNumber = BigInt(9_007_199_254_740_991_345)
console.log(typeof longerNumber) // returns bigint
console.log(longerNumber) // returns 9007199254740990976
. They cannot Math, you cannot convert a BigInt value to a number. It is useful in contexts requiring precise handling of large integers, such as cryptography,
or when interacting with databases that use large integer identifiers.
Parent Element
.parentElement
Add to the end of an element to find its parent element.
childElement.parentElement
would return the parent element of the selected child element.
Console Log Static Method
console.log()
You can pass in parameters. console.log(param1, param2)
To get wether or not a checkbox/radio was checked, get the element and add .checked, element.checked will return a boolean.
const isChecked = document.querySelector('input[type="radio"]:checked').value will grab the radio element if it is checked.
To switch the value of a boolean (false to true, true to false) write boolean = !boolean
Using else if instead of another if, will prevent the system from reading unused code if it was already true in the first if.
Conditionally Render CSS
Giving elements different classes under different conditions.
let boolean = false;
thingToClick.addEventListener('click', function(element){
boolean = !boolean;
if(boolean){
booleanClass = 'className';
};
let booleanHTML = <div class="${booleanClass}">></div>
});
UUID
Universally Unique Identifiers
A string of 36 characters.
Often used to identify pieces of data.
Highly likely to be globally unique.
Also known as GUID, or Globally Unique Identifier.
You can have a UUID created with a CDN
One of the most popular tools for generating UUIDS is UUID JS. To copy this, go to the readme, select
the CDN Builds link, copy the import, paste it in your project (test it). Make sure your html has
type="module" in the script tag. Return the uuidv4 function (you can rename that) as a function
uuidv4()
arrayName.unshift(element) adds the element to the beginning of the array.
Object Destructuring
Extract properties from objects.
It enables us to extract properties from objects into distinct variables.
Helps keep your code DRY.
const {propertyVariableName, propertyVariableName2, propertyVariableName3} = objectName
console.log(`display this ${propertyVariableName}'s value`)
The .map() Method
Iterating over arrays.
const newArray = oldArray.map(function(nameValues, index) {
//iterates through each array value
//index will return the index of each value
})
could be stored in a function instead of a const.
Use .map() if you need to make use of the new array it returns
The .join() Method
Strings from arrays.
Concatenates elements of an array into a string.
You choose how elements are separated.
It returns the new string.
console.log(arrayName.join('what you want between each value'))
To have no seperator just keep an empty string, there will be no space between them though.
All methods must end with parenthesis.
To find out what type an element is put typeof before it. It will return if it's a string, boolean, ect.
console.log(typeof booleanEl)
would return boolean.
You can only chain onto a method if it returns an array.
The For Loop
break and continue can be use within for loops.
for (let i = 0; i < arr.length; i++){} is a common for loop.
for (let i = 0; i < arr.length; i++){
if (arr.key < 5){break}
if (arr.key > 5 {continue}
console.log('this will not run if the arr.key is greater than or less than five'))
}
Various Array Methods
arr.every(function(arrItem){
return arrItem >= 30
}) Every array item will be subject to the code within the function, and you will get a boolean true or false response. It will only return true if every item is true.
.some(function(arrItem){
return arrItem >= 30
}) Every array item will be subject to the code within the funciton, and you will get a boolean true or false response. It will return true if one or more items are true.
arr.find(function(arrItem){
return arrItem > 30
}) Every array item will be subject to the code within the function until one is true, you will get the items content as a response. If none are true, then it will
return undefined.
.findIndex(function(arrItem){
return arrItem > 30
}) Every array item will be subject to the code within the function until one is true, you will get the items index number as a response. If no item is true, it will return -1.
arr.indexOf(arrItemContent) Every array item will be tested for the content until one is found with it, then it will return that items index number.
arr.at(-1) Takes a positive or negative integer and returns the item at that index. Negative integers will count back from the end of the array.
Replace Method
text.replace(pattern, replacement)
const text = "hello how are you?"
text.replace('h', 'H')
will return 'Hello how are you', changing the first h but not the second.
ReplaceAll Method
text.replaceAll(pattern, replacement)
const text = "hello! how are you this morning?"
text.replaceAll('h', 'H')
will return 'Hello! How are you tHis morning', changing the all h to H.
To avoid the above problem of capitalizing letters within words you can use regex (regular expression). This is a sequence of characters that specifies a match pattern in text.
/[a-zA-Z1-9]/ will find any number 1-9 and any letter, lower or uppercasea-z.
/^\d{5} (-\d{4})?$/ will validate US zip codes.
In this case you would do text.replaceAll(/\b(h)\b/g, 'H')
You can also use functions in the replaceAll.
const text = "I love you with all my heart!"
console.log(text.replaceAll(/\b(love|heart)\b/g, function(match){
return `${match} <3`
}))
will log "I love <3 you with all my heart <3".
RegExp
\d = any number between 1 and 9
. = any single character
[abc] = will match a, b or c
[^abc] = all but a, b or c
[0-6] = will match any single 0, 1, 2, 3, 4, 5 or 6
[^a-p] = will match q through z
\w = includes any single alphanumeric character plus the underscore
[a-z] is different then [A-Z]
a{3} = aaa
[wxy]{5} = any sequence with exactly 5 characters that are either w, x or y
.{2,6} = matches any sequence that is between 2 and 6 characters long
\d = any single digit between 0 and 9
a* = 0 or more of a
ab?c = abc or ac (b is optional)
_ = a space
\t = tab
\n = new line
\r = return
\s = any white space
\S = no white space
g = g flag = global = looking for all instances, not just one. Needed if you are using replace all after the ending /
i = i falg = case insensitive =
regexp has a test method that returns a boolean.
regex.test(text)
There is a RegExp Constructor.
const textText = "hello world"
const regex = new RegExp(testText, 'gi')
Primitives, strings, numbers and booleans are passed by value.
Objects and arrays are passed by reference.
There are two ways to copy arrays, Deep Copy and Shallow Copy.
Shallow Copy creates a new object or array but only at the first level. For nested objects or arrays, a shallow copy Will
still hold references to the original nested objects or arrays.
Deep copy copies the entire array or object.
To one element with a given id use getElementByid('idName').
To grab all elements with a given class use getElementsByClassName('className').
You can usually get rid of an else if you are returning in the if.
Function Expressions
Different Syntax and Behavior.
Are not hoisted (cleaner).
const name = function(parameter){}
Arrow Functions
Ultra Consise functions.
One parameter:
const name = parameter => { return stuff }
or
const name = (parameter) => { return stuff }
You have to add the curly braces and return keyword when there's more complex logic, but when it's one simple line of code you don't need the curly braces and return keyword.
If you don't return anything it is undefined.
Import and Export
Name Export
To rename what you're importing ad an as
import { oldName as newName } from 'fileLocation'
To import multiple things from one file, use a comma
import { oneThing, secondThing } from 'fileLocation'
You must export them both, but if you do you have to name every name export that is passed in that import.
To export multiple exports export { exportNameOne, exportName2} or export function(){} exports the function.
Gives you the advantage of calling this function whatever you want. Renaming the function can cause
confustion and make code less readable.
import nameYouWant from './fileLocation.js'
You can only have one default export from a file.
Anytime you use the import or export in JS you have to add type="module" to the HTML JS file reference.
The .reduce() Method
Returns only one thing from an array.
Takes in a function.
Iterates through the array given the parameters till it has combined all values.
arrayName.reduce(function(total, currentElementb ){})
Must use return keyword.
To get a value of an array
Written as arrow function
const totalOfArray = arrayName.reduce(
(param1, param2) => param1 + param2,
);
When using objects and returning numbers with a reduce method
const total = array.reduce(function(total, currentElementb){
return total + currentElementb.numbersKey
}, 0)
The 0 will set the default start of the total to be 0, instead of an object.
Default Parameters
Protection against bugs.
function functionName(arrayName, secondParam = defaultValue){}
The defulat will only be used when you don't pass in an argument when calling the function.
The Ternary Operator
An alternative to if/else (sometimes).
condition(true or false value) ? expression(executes if true) : expression(executes if false)
condition ? ifTrue : condition ? ifTrue : else
Complex login is not easy to read with a ternary operator.
The Rest Parameter
Catching the rest of the arguments.
function functionName(parameter, ...restParameterName){
//iterates through restParameterName as many times as there are parameters for it.
}
functionName('param1', 'param2', 'param3', 'param4', 'param5',)
//Would go through function for all entered params 1-5
Really good way of making a copy of an array
const arrayOne = ['arrayStuff1', 'arrayStuff2', 'arrayStuff3']
const arrayOneCopy = [...arrayOne]
console.log(arrayOneCopy)
//logs ['arrayStuff1', 'arrayStuff2', 'arrayStuff3']
To find the highest number of a list of numbers use Math.max(numberlist).
To find the loweset number of a list of numbers use Math.min(numberlist).
Short-Circuit
More concise code for conditional logic.
The logical OR operator ||. Evaluates from left to right and stops evaulating once it finds something truthy.
const arrayName = {
key1: 'value1'
//key2: 'value2'
}
const variable = array.key2 || 'That key does not exist'
console.log(variable)
//logs 'That key does not exist'
The logical AND operator &&. Evaluates from left to right and if the stuff on the left is true, executes the stuff on the right
const exampleArray = {
key1: 'value1'
}
exampleArray.key1 === 'value1' && console.log('This is ran')
//logs 'This is ran'
exampleArray.key1 === 'value2' && console.log('This is not ran')
//nothing is logged
Nullish Coalescing Operator, ??, returns the right hand operator truthy value if the left hand operator is null or undefined.
Optional Chaining, ?., adds optional additions to your chain.
const library = {
sections: {
fantasy: [
{title: 'The Long Way to a Small, Angry Planet'}
]
}
}
console.log(library?.sections?.fantasy[0]?.title)
Would log 'The Long Way to a Small, Angry Planet'. If anything is wrong, it will log undefined, instead of throwing an error.
Switch Statements
Select one of many code blocks to execute.
function functionName(parameter){
switch(parameter){
case 'parameter possiblity';
//the following code will only run if the case is correct
break //won't run the code below
case 'another possibility':
//the following code will only run if the case is correct
break
default:
//runs if none of the cases are true
}
}
The last item (default or case) does not need a break.
Constructors
Constructors have two main categories, Inbuilt and Custom.
Inbuilt Constructors provide objects in various predetermined formats, like Date Objects and Error Objects,
and Objects for each data type.
Custom Constructors are constructors we design ourselves to provide objects for our own specific purposes.
The Date Constructor
An inbuilt constructor.
To use the Date() constructor
const nameofThing = new Date()
//returns an object
//return example: 2024-06-27T22:42:07.898Z
//To make it more readable put
nameofThing.toString()
//return example: Thu Jun 27 2024 16:43:55 GMT-0600 (Mountain Daylight Time)
//gives exact date and time of where you are
To return the current year use
new Date().getFullYear()
luxon makes working with dates and times easier.
The Error Constructor
throw new Error('Your error here')
The throw keyword will stop all the code after your throw from running.
Code will continue running after your error
console.log(new Error('Your error here'))
The Object Constructor new Object() will create a new object. Much better to use the litteral {}
String()
Number()
Array()
Boolean()
The Error() Constructor
throw new Error('error text')
throw will stop all following code from executing.
Other Constructors are String() Number() Array() Object() Boolean() but they are rarely used.
You can add a function to within an object and access it.
const objectName = {key1: 'value1', key2: 'value2', key3: function(){}}
objectName.key3()
this can be used within an object to refer to the object name instead of typing it out.
If you are using an arrow function within the object using this will refer to what's beyond the function (window).
To intentionally throw an error
function functionName(parameter){
try {
if (typeof parameter === 'number'){
console.log(parameter)
} else {
throw new ReferenceError('Error Message')
}
} catch (err) {
console.log('Error: ' + err)
}
}
functionName('String')
//logs "Error: ReferenceError: Error Message"
Helpful Debugging Tool
In inspector (ctrl/cmnd + i), find Sourches, Breakpoints (Run code until a breakpoint, allowing you to see what happens up to that point. Great to execute code step by step until you find the problem.)
, Watchers (Monitor the values of variables or expressions overtime as you step through your code. useful to see how and when a value changes during your code.).
The Heap - handles memory allocations so we don't have to.
The Call Stack - where code executes - As js is single threaded, the call stack can only excecute one piece of code at a time in its single thread.
Js is helped by WebAPIs, task queue, and event loop, all are not a part of the js language.
JS can multi-task (.setTimeout(), .setInterval(), fetching data across the network, promises).
The webAPI is what counts for timeouts and intervals. After the time is done it passes the code to the Task Queue, which will send the code at the top of the queue to the call stack once it is empty.
If code is complex, the execution of setTimout and setInterval will take longer. It will never take the exact ms you put in, just slliiiiightly above it. Unoticable.
performance.now() is a really super accurate timestamp.
++Pre-increment, just move the increment opperator to the front of your expression.return ++count. The pre-increment operator increments the variable's value before the result of the increment is used in an expression.
--Pre-decrement, just move the decrement opperator to the front of your expression.return --loss. The pre-decrement operator decreases the variable's value before the result of the decrement is used in an expression.
Number Separators will separate out the digits into chunks
Object.assign()
Makes a shadow copy of an object.
Copies properties from a source object to a target object
const obj = {
key1: 'value1',
key2: 'value2',
key3: function(){
console.log(this)
}
obj.key3()
}
will log {key1: 'value1', key2: 'value2', key3: ƒ()}. If you use an arrow function it will log out "window" instead.
The Prototype Chain is the order in which things can be inherited by Objects. The top one inherits from Object.
Polymorphism an object can override inheritance, adapting for specific needs. It allows methods to have different implementations
on different objects. An object can override a method it inherits, adapting it for specific needs.
Not properties of this in the same way public properties are.
class ClassName {
#privateProperty
constructor(privateProperty, param2){
this.#privateProperty = privateProperty
this.param2 = param2
}
}
const variable = new ClassName('privateProperty', 'param2')
variable would log out ClassName {param2: param2}
Access Private field with getters and setters
Getter:
class ClassName {
#privateProperty
constructor(privateProperty, param2){
this.#privateProperty = privateProperty
this.param2 = param2
}
get privateProperty(){
return this.#privateProperty
}
}
const variable = new ClassName('privateProperty', 'param2')
logging variable.privateProperty will give you privateProperty
Still can't be modified so access is controlled.
Setter:
class ClassName {
#privateProperty
constructor(privateProperty, param2){
this.#privateProperty = privateProperty
this.param2 = param2
}
get privateProperty(){
return this.#privateProperty
}
set privateProperty(newPrivateProperty){
if (typeof newPrivateProperty !== 'string' || newPrivateProperty.length >= 0){
throw new Error('newPrivateProperty is not valid')
}
this.#privateProperty = newPrivateProperty
}
}
const variable = new ClassName('privateProperty', 'param2')
variable.privateProperty = 'newPrivateProperty'
Can be modified.
Symbols
A primitive data type
An immutable identifier used as a property key in objects.
Each symbol is unique
A bit like UUIDs/GUIDs, but built in to js.
const symbolVar = Symbol('description'), you don't use a new keyword, and the description does not effect it's uniqueness.
To store a symbol in an Object
const objName = {
key1: 'value1',
[Symbol('description')]: 'value2'
}
or
const symbolVar = Symbol('description')
const objName = {
key1: 'value1',
[symbolVar]: 'key2'
}
or (most common)
const symbolVar = Symbol('description')
const objName = {
key1: 'value1',
}
objName[symbolVar] = 'key2'
You won't be able to see the symbol unless you specifically ask for the symbol like
console.log(objName[symbolVar])
Used to add properties to objects without the risk of property name conflicts.
Symbols are not 100% private.
Misuse or overuse of symbols can lead to the confusion or coplexity in code maintenance.
Map Object
Has nothing to do with the array map method.
The map object holes key/value pairs just like a regular object.
Map Object Benefits
Use other data types as keys
const objOne = { key1: "value1", key2: "value2" }
const mapObj = new Map()
mapObj.set(objOne, 10000)
logs the map object, key as objOnes content and the value as 10000
Many of the methods do not have wide browser support.
Closures
Helps you access variables defined within a funciton, outside of said funciton.
function outerFunction(param) {
const outerVariable = 'I am from the outer function'
function innerFunction() {
console.log(outerVariable)
console.log(param)
}
return innerFunction
}
const closure = outerFunction('I am an argument')
closure()
logs I am from the outer function I am an argument.
IIFEs
Effectively self calling.
To immediately run a function wrap the function in () and end it in ().
(function() {
function stuff
})()
(async function(param) {
function stuff
})('param')
Recursion
Function calling itself
Recursive Function
To reverse a number
function countdown(count) {
console.log(count)
if (count = 0) {
return count
}
countdown(count - 1)
}
countdown(5)
logs 5 4 3 2 1 0
Unwind to return the final value.
To reverse a string
function reverseStr(str){
if (str.length <= 0){
return str;
} else {
return reverseStr(str.slice(1)) + str.slice(0, 1);
}
}
Written as an arrow function
const functionName = param1 => param2 => param3 => `${param1} ${param2} ${param3}`
Why Curry a Function?
Allows for partial application, which allows you to fix some arguments and defer the rest. This is useful when you repeatedly call a function with some of the same arguments.
Ensures a function is called at most once in a specific period of time.
When an event continuously triggers, throttling will call the function only at regular intervals, ignoring any additional triggers.
Put a throttle on a resize event handler
function handleResize(e){
console.log('resize happened on event' + e)
}
function throttle(func, delay){
let throttleTimeout = null
return function() {
if(!throttleTimeout){
func()
throttleTimeout = setTImeout(() => {
throttleTimeout = null
}, delay)
}
}
}
const throttleHandleResize = throttle(handleResize, 1000)
window.addEventListener('resize', throttleHandleResize)
Add an event to the throttle
function handleResize(e){
console.log('resize happened on event: ' + e)
}
function throttle(func, delay) {
let throttleTimeout = null
return (...args)=> {
if(!throttleTimeout) {
func(...args)
throttleTimeout = setTimeout(()=> {
throttleTimeout = null
}, delay)
}
}
}
const throttledHandleResize = throttle(handleResize, 1000)
window.addEventListener('resize', throttledHandleResize)
Debouncing
Reduces Unecessary code execution.
Ensures a function is called only after a certain period has passsed since the last triggering event.
When an event continuously fires, debouncing will delay the function call until after the event has stopped for a specified duration.
Use debouncing with an input change event listener
function debounce(func, delay) {
let debounceTimer
return (...args) => {
clearTimeout(debounceTimer)
debounceTimer = setTimeout(()=> {
func.apply(...args)
}, delay)
}
}
function handleInput(e) {
console.log('Input detected from element with id ' + e.target.id)
}
document.getElementById('name-input').addEventListener('input', debounce(handleInput, 500))
Generators
Common use cases
Async operations
Handling state
Lazy evaluation
Using lazy evaluation
const slidesArr = [
"1",
"2",
"3",
"4",
"5"
]
function* generator(arr) {
for (const item of arr) {
yield item
}
}
const slideGenerator = generator(slidesArr)
document.getElementById('nextSlideBtn').addEventListener('click', () => {
const result = slideGenerator.next()
if (!result.done) {
console.log(result.value)
} else {
console.log('That is the end!')
}
})
logs 1 2 3 4 5 That is the end!
The return keyword can stop a generator yeilding.
const slidesArr = [
"1",
"2",
"3",
"MALFUNCTION",
"4",
"5"
]
function* generator(arr) {
for (const item of arr) {
if (item === 'MALFUNCTION') {
return
} else {
yield item
}
}
}
const slideGenerator = generator(slidesArr)
document.getElementById('nextSlideBtn').addEventListener('click', () => {
const result = slideGenerator.next()
if (!result.done) {
console.log(result.value)
} else {
console.log('That is the end!')
}
})
logs 1 2 3 That is the end!
Functions are a first class object in js.
To clear a form, use form reset form.reset()
Async JavaScript
Code that can be run out of order. Allows a lengthy operation to start, but finish at a later time without blocking other code from running in the meantime.
JavaScript isn't truly asynchronous, but rather has 'callback' mechanisms in place to run commands in a different order to make things more efficient.
'Single-threaded' meands only one command can run at a time.
function callback() {
console.log('ran')
}
document.getElementById('button').addEventListener('click', callback)
function callback(){
console.log('ran')
}
setTimeout(callback, 2000)
function returnStuff(param) {
return param.thing
}
const newArray = oldArray.filter(returnStuff)
Promises
There are three promising states.
Pending is one state, it means the promise has yet to be completed.
Following pending, is a Fullfilled state, it means the promise was completed as promised.
Alternatively, after pending can be the Regected state, which means the promise was not completed as promised.
.then() returns a promise, you can use this for promise chaining.
.then() is a method that will take in a callback function.
When a promise (fetch) is fulfilled it will start running the .then() block.
To get the children of an element
for (const child of myElement.children) {
console.log(child)
}
Async and Await
Introduced in ECMAScript 2017 (ES8)
Makes asynchronous code appear to be synchronous.
async goes before the function
await goes before a method/function that returns a promise.
async function functionName() {
await function or method that normallyreturns a promise
}
async function functionName() {
const name = await function or method that normallyreturns a promise
}
You can put async before an arrow funciton.
To get the exact time without the date use
const time = new Date().toLocaleTimeString('en-us', {timeStyle: 'short'})
To tell if a string starts with something specific you can use the startsWith method: string.startsWith('test'). It will return true or false.
Resources
Create a UUID with a CDN
Current most common is Version 4 UUID, as it uses randomly generated characters.
One of the most popular tools for generating UUIDS is UUID JS. To copy this, go to the readme, select the CDN Builds link, copy the import, paste it in your project (test it).
Make sure your html has <script type="module" src="jsFile"></script> as the script tag. Return the uuidv4 function
(you can rename that) as a function uuidv4().