Math.random()
always chooses a random number between 0 and 1. The Math.round()
rounds the number to the nearest integer. Therefore, using Math.round(Math.random() * number)
can get random numbers greater than 1. e.g. Math.round(Math.random() * 3)
would return a random integer between 1 and 3.Math.round()
rounds to the nearest integer, and it has 2 variations: Math.ceil()
and Math.floor()
which round up and down, respectively..toFixed()
function which lets you round to a specified decimal place.`
and ${}
. e.g. confirm(order.name + ": place the order for " + order.item + "?")
could also be written as confirm(`${order.name}: place the order for ${order.item}?`)
.join()
which lets you concatenate with a custom string that you put in between the brackets. e.g. console.log(arrayName.join(", "))
would list all the values of the array separated by ", ".console.log(input)
prints the output to the console. In a .html file, this can be accessed using chrome dev tools, and navigating to the Console tab. e.g. console.log("Hello World")
or console.log(24 == 2*12)
var variableName = variable
, e.g. var favouriteColour = "blue"
var penColour = "black"
. Note that strings are alphanumeric - any text enclosed in (either single or double) quotes can be a string.var age = 18
. Number variables can be both integers or floats/decimals.var status = true
. Booleans are binary variables - either true or false.console.log(typeof age)
(if the above variables were also stored in the JS file) would return number
in the console.var a = 10
and var b = 2
.console.log(a + b)
returns 12console.log(a * b)
returns 20console.log(a - b)
returns 8console.log(a / b)
returns 5%
which returns the remainder from a division. For example, console.log(4 % 15)
would return 3.==
for just comparing values, and ===
to check strict equality. Similarly, !=
and !==
will check for just values, and both values and data type, respectively.<
or >
for (strictly) greater than or less than; and <=
and >=
for greater than or equal to and less than or equal to.var test1 = a * b
) and then compare them using that method.&&
. The output of this: console.log(test1 && test2)
would be a boolean value, either true or false. It would compare the values of 2 expressions, test1 and test2, then check to see if their values match, and print either true or false to the console.||
. The ouput of this: console.log(test1 || test2)
would also be a boolean value but if either test1 or test2 were true, the console would print true.var arrayName
= [item1, item2, item3, etc.]
var names = ["Adam, "John", "James", "Leo"]
then typing something that references "names", e.g. console.log(names)
would return the entire array.console.log(names[1])
would return John, (not Adam).names[0] = "Alex"
would redefine the 0 index (formerly Adam) with the string "Alex".console.log(arrayName.length)
. Adding .array
onto the end of an array name will return the number of items inside the array - it can be used outside of console.log()
too.console.log(arrayName[arrayName.length -1])
console.log(arrayName.at(-1))
. Swapping -1
for any number can therefore find the nth last item.var bankAccount = {
user: {
firstName: "Name",
lastName: "Surname",
address: {
houseNumber: "house number",
city: "city name",
postcode: "postcode",
nearestBranch: ["branch1", "branch2", "branch3"]
}
}
balance:{
primary: 10000,
savings: 12093,
investmentISA: 1023102
}
}
.keyName
or [keyName]
; and you can access arrays in the same way too: arrayName[i]
.var
is considered lexical scoping.const
and let
as used in loops or if statements, are considered "block" scoping. What this means is the variables set with those keywords will only exist inside that block of code. This allows for a greater precision of when the variable is used - it is even narrower than local scope.alert("Hello world")
confirm("Typically a question")
. Because a confirm prompt requires a user input - clicking "Ok" returns true, and "Cancel" returns false - it can be used with variables to get user-defined variables easily. e.g. var variableName = confirm("question")
. The answer chosen by the user will now be stored in variableName.prompt("Typically a question")
. Again, using this with variables is an easy way to gather user input, e.g. var variableName = prompt("question")
- and this time the answer can be anything the user types in the prompt input field. Even if the user types a number here, the result will always be a string.if (condition) {
code to run if condition is true
}
if (hungerLevel <= 20){
console.log("I'm hungry!")
}
if (hungerLevel <= 20){
console.log("I'm hungry!")
} else {
console.log("I'm full.")
}
if (condition1){
code to run if condition1 is true
} else if (condition2) {
code to run if condition2 is true
} else if (condition3) {
code to run if condition3 is true
} else {
code to run if no conditions are met
}
switch (variableName) {
case value1:
code to run if the variable is value1;
break;
case value2:
code to run if the variable is value2;
break;
}
default
case to the code block. This will return only if no other conditions are met in the switch statement.
code to run if the variable is value2;
break;
default:
code to run if the variable is not any of the cases above
}
for (expression 1; expression 2; expression 3) {
continue here
}
for (var i = 0; i <= 20; i++){
console.log("i is less than or equal to 20.")
}
i
in the iterator is just a variable, it starts at 0 (or the first item in an array). The stopping condition is when i is strictly greater than 20 (i.e. the for loop will run as long as i is less than or equal to 20), and the means of increasing the iterator is i++
which is shorthand for i = i + 1
. This way every time the for loop runs, i
becomes closer and closer to meeting the stopping condition.
var
inside a loop and a variable of the same name exists outside the loop, that variable will be redefined. If you use let
the variable declared there will only exist inside that loop.
var i = 3
for (var i = 0; i <= 20; i++){
console.log("i is less than or equal to 20.")
}
i
would be 20 after the loop, as it was redefined as 0, then for as long as i
was less than or equal to 20, it kept increasing by 1, until it reached 20 and the loop stopped.
var i = 7
for (let i = 0; i <= 20; i++){
console.log("i is less than or equal to 20.")
}
i
remains 7, even though it was redefined as 0 and increased to 20 - those actions happened only inside the for loop.
var arrayName = ["item0", "item1", "item2", "item3"];
for (var i = 0; i < array length; i++){
action to apply to each array item
}
var animals = ["chicken", "duck", "cat", "shark"];
for (var i = 0; i < 4; i++){
var currentAnimal = animals[i];// This sets the current array item as a variable so we can manipulate it easier.
console.log(currentAnimal + "s")// This will print the current animal with an "s" appended, to make it the plural form of the word.
}
function functionName(input parameter) {actions}
. The functionName
is any name, typically one that describes the action the function is taking. The input parameter
is not necessary, but if used typically describes what type of data the function will run on, and must be used if the function has a functionInput
to refer to that input. The actions
are what actions you want the function to take.
functionName(functionInput)
. e.g.:
var fruitsA = ["pears", "apples", "oranges"]
var fruitsB = ["pineapple", "peach", "mango"]
function listFruits (arr) {
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
}
listFruits(fruitsA)
listFruits(fruitsB)
function functionName(input1, input2) {}
return
keyword - this is useful for getting outputs from functions.return
keyword exits a function once it is read within the function. This can be used to avoid running through other lines of a functionvar functionName = function(inputParameters) {}
. It can be called in the same manner.var planet = {
name: "Earth",
age: "4.543 billion years",
moons: 1,
isPopulated: true,
population: "8.045 billion",
}
objectName.keyName
or objectName["key Name"]
, if the keyname is a string. You can use the []
method for regular key names too, but you can't use strings with the .
method..log
or .random
. The only difference between a method an a function is that a method lives inside an object.Object.keys(objectName)
to list all the keys, Object.values(objectName)
to list the values and Object.entries(objectName)
to list all the entries (keys and values).var prices = Object.values(menu);
console.log(prices);
var totalprice = 0.00;
for (let i = 0; i < prices.length; i++) {
const price = prices[i];
totalprice += price;
}
console.log(`The total price for all items is £${totalprice}`)
objectName.keyName()
BUT you must add ()
afterwards.
var person = {
name: "myName",
age: 21,
tellFunFact: function () {
console.log(`My favourite number is ${1+2}`)
}
}
person.tellFunFact()
this
keyword references the outermost object. If you use console.log(this)
the console will log the "Window" object, which keeps track of all the information and everything the user can see, e.g. viewport, HTML, etc. It is the outermost object we have to deal with when coding in the front-end in JavaScript.this
keyword can more usefully be used inside our objects/methods though. It'll refer to the object it is contained inside.var user = {
name: "J",
surname: "G",
age: 21,
displayUser: function() {
console.log(`The user is ${this.name} ${this.surname} and they are ${this.age} years old.`)
}
}
user.displayUser()
The user is J G and they are 21 years old
, despite the method itself being inside the object.arrayName.sort()
returns a sorted array in alphabetical order.arrayName.push()
adds elements to the end of an array. Can take more than one parameter.arrayName.unshift()
adds elements to the beginning of the array. Can also take more than one input.arrayName.slice(start index, stop index)
. e.g. writing arrayName.slice(3,6)
would start a new array with the 3rd index of the first array, and take the 4th and 5th indices, but stop before the 6th index.arrayName.join(separator)
joins all items of an array with the specified separator
.arrayName.splice(start index, number of items to delete, item(s) to add).
. e.g. arrayName.splice(4,2,"apple","pear")
would remove the 4th and 5th index (which are the 3rd and 4th items) of the arrayName
array, and insert "apple" and "pear" into the array starting at the 4th index.stringName.split(separator)
separates a string into individual items of an array every time the separator
appears. e.g. string.split(",")
would split the original string into parts every time there was a ,
. If the separator
is left blank, the string splits at every character.stringName.replace(characters to replace, characters to replace with)
does what it says.arrayName.forEach()
iterates through each item of an array and applies an action (defined within the ()
) to it. When used with a function, this removes the need to write a for
loop, as you can just use arrayName.forEach(functionName)
instead.arrayName.map()
puts all items of an array into a new array (when used with a new array name). Again, when used with a function, it allows you to map out a new array with ease. e.g. var newArray = oldArray.map(functionMultiply)
.for... of...
loop can be used to iterate through an array. It should be used in preference to forEach
.document.querySelectorAll()
, for instance, which generates an array (of objects).var filteredArray = arrayName.filter(functionName)
, where the function is the filtering method - actions you apply to first array to get the second array. e.g.:
var nums = [1, 20, 30, 3, 5, 8]
function lessthan10(num) {
return num > 10
}
var smallNums = nums.filter(lessthan10)
var filteredArray = arrayName.find(functionName)
.this
attribute refers to the outermost object to where it is placed. Unless inside a custom function/method etc, it will refer to the window..children[index number]
to navigate throught the children of an object too, and using console.log(document.body.children)
would list the children of the body object, for example, as an array.
console.log(window)
shows the window object and all its members.console.log(window.document)
shows the document object and all its members - this is similar to the HTML document.console.log(element)
shows the specified element and all its members.console.log(document.head)
shows the header tag and all its members, as in a HTML file.document.querySelector()
, which would find the first element that matches, or document.querySelectorAll()
, which would provide an array of all elements that match.
document.querySelector("#exampleID")
or document.querySelector(".exampleClass")
. You can also use tag names here. Besides querySelector
, there are several ways to target more specifically:
document.getElementbyId()
document.getElementbyClassName()
document.getElementbyTagName()
#
or .
, etc. as it already specifies what it is searching for..value
method in conjunction with a variable to store it, e.g. var recordedInput = document.querySelector("element").value
.trim()
removes any blank space before and after a value. e.g. javascript
would be shortened to javascript
.style
method. You can also change other properties with other methods, e.g.:
var textbox = document.querySelector("#setattribute > ul > li:nth-child(1)")
textbox.style.color = "red"
textbox.style.fontFamily = "monospace"
.style.attribute
for each attribute, you can use .setAttribute("attributeName", "attributeValue(s)")
e.g. document.querySelector("#customClass").setAttribute("style","color: yellow; font-size: 0.85rem; text-decoration: underline;")
would set the first element with the class customClass
with the style attributes listed above.
document.querySelectorAll()
(which generates an array of all elements that match the requirements), you can adjust multiple things quickly:
var listEls = document.querySelectorAll("li")
listEls.forEach(element => {
element.setAttribute("style","color: yellow; text-decoration: underline;")
});
document.querySelector("img").setAttribute("src", "example.gif;")
document.createElement(element name)
.document.body.the path where you want to insert the element.appendChild(element)
..textContent()
.
var ele = document.createElement("li")
ele.textContent = "This text was created and added to the DOM by JS."
document.querySelector("#createappends > ul").appendChild(ele)
targetElement.addEventListener("type", "function())
. The targetElement
is the element in the DOM (accessed via document.querySelector()
, for instance); the type
is the type of interaction to listen for: i.e. click
or mouseover
; and function()
is the function that will run (can be written in place, or defined beforehand).event
parameter can also commonly be written as just e
or omitted entirely if not used within the function.
evListenerObj
is a predefined object.
evListenerObj.addEventListener("mouseover", function(event) {
event.preventDefault()
console.log(event)
alert("Hey :)")
})
.preventDefault()
within the function of the event listener. This is where the event
or e
parameter can be used, as you would write it out like: event.preventDefault()
. This should be used by default.event.target
will show what element triggered the event, even if that's the child within the parent which had the event listener.change
type. This listens for a change in the value of an object - for example, on a dropdown menu:
This text will change based on the value of the dropdown menu above.
var changekeybevent = document.querySelector("#changekeybevent");
var ckbParent = document.querySelector("#keyboardevents > ul > li");
var ckbChild = document.querySelector("#keyboardevents > ul > li > p");
var newText;
changekeybevent.addEventListener("change", function(event){
event.preventDefault();
newtext = changekeybevent.value;
ckbChild.textContent = newtext;
})
keydown
event type is also useful. It listens for any keypress (except backspace).
var keydownevent = document.querySelector("#whatdausertypin")
var textareakeydownevent = document.querySelector("#keydownevent")
textareakeydownevent.addEventListener("keydown", function(event){
var key = event.key.toLowerCase()
var alphanumericchars = "abcdefghijklmnopqrstuvwxyz0123456789 ".split("")
if (alphanumericchars.includes(key)) {
keydownevent.textContent += event.key
}
})
submit
event type listens for when the Enter button is pressed inside a form input field.click
event, and the parent does too, both events would trigger when the child is clicked.event.stopPropagation()
rather than the event.preventDefault()
.setInterval(function, delay)
. The delay, in milliseconds, is the delay before the function is repeated.setInterval()
is that multiple timers cannot run at the same time - so there needs to be a way to remove the timer or stop it before another one is run. This is done with clearInterval()
, inside the brackets you put the variable name that you assigned the setInterval function to previously.
var timerInterval = setInterval(function(){
secondsLeft--;
timerbutton.textContent = `${secondsLeft} seconds left until timer is up.`;
timerbutton
is also a predefined variable referring to an element in the DOM).
if (secondsLeft === 0) {
clearInterval(timerInterval);
timesUp();
}
timesUp()
will be called, and the timerInterval
will be cleared, preventing this timer from running further.
}, 1000)
<img
src="https://techcrunch.com/wp-content/uploads/2015/10/14.gif?w=700&crop=1"
data-state="gif1"
data-gif1="https://techcrunch.com/wp-content/uploads/2015/10/14.gif?w=700&crop=1"
data-gif2="https://techcrunch.com/wp-content/uploads/2015/10/22.gif?w=700&crop=1"
/>
element
.getAttribute("data-state
")
data state
is to use element
.dataset.state
: the dataset
is equivalent to the data
from the HTML, and the .state
is equivalent to the -state
.if
loop.localStorage.setItem("key
", "value
")
.localStorage.getItem("key
")
.localStorage.removeItem("key
")
localStorage.setItem("key
", JSON.stringify(value
))
.user = {
name: "john",
surname: "doe",
email: "john_doe@gmail.com",
password: "password123",
}
localStorage.setItem("user", JSON.stringify(user))
localStorage.getItem("user")
would retrieve the data but as a STRING not its initial data type.JSON.parse(localStorage.getItem("key
"))
.document.getElementbyId("header")
in vanilla JS would be $("#header")
in jQuery.console.log($())
.$("element tag /.element class / #element ID")
.
<>
) as that would create an element not reference it. However, when searching for classes/IDs .
or #
must be used.$("input[name="firstname"]")
would reference the following HTML element: <input type=text name=firstname>
$("<tag>")
, e.g. $("<h1>")
to do what vanilla JS does with document.createElement("h1")
..append("The element as it would appear in HTML")
, e.g. .append("<p class="m-5" id="newEl">This element was created with .append</p>")
.textContent = "string"
, i.e. alter text content of elements use .text("string")
..append(element)
to append elements to an object in the DOM (equivalent of vanilla JS .appendChild(element)
)..attr("attribute", "value")
or for specifically adding a class, you can use .addClass("class")
..css("style", "value")
.
element.css({
"background-color": "black",
"color": "red",
"font-size": "30rem"
})
element.remove()
. It removes all matching elements when searching by tag or class, but only the first if searching by ID.element.hide()
is a quick way to hide the element.var placeToAddTheNewElement = $("#jqueryaddhere");
var newBulletPoint = $("<li>");
newBulletPoint.text("This element was created with jQuery.");
newBulletPoint.css("color", "yellow");
newBulletPoint.attr("id", "jqueryaddedelement");
placeToAddTheNewElement.append(newBulletPoint)
element.children()
. The children of an element can be manipulated by just chaining on arguments, e.g. element.children().css("color", "yellow")
, which would change all the children to font colour yellow.element.children().eq(index)
.
var jqueryDOMsect = $("#jquerydom")
jqueryDOMsect.children().children().eq(1).addClass("yellowtext")
element.children(element)
such as element.children("h3")
..parent()
..siblings()
, or .next()
to find the next sibling and .prev()to find the previous one.
event.preventDefault()
with forms, as before, to prevent it from refreshing the page.<input type=checkbox value=value>
, the way to select all checked options is $("input:checked")
$.each(array, function)
is an equivalent to the "for" loop, allowing you to iterate through each item of an array and apply a function to them.$.each()
, using $(this)
references the current value the loop is iterating over.function handleFormSubmit(){
var checkedEl = $("input:checked")
var selected = []
$.each(checkedEl, function(){
selected.push($(this).val());
console.log(selected)
})
$("#checkboxes").text(`Fruits: ${selected.join(", ")}`)
$("input[type='checkbox']").prop("checked", false)
}
$("#submit").on("click", handleFormSubmit)
type=text
forms, data can be submitted with the event type submit
, as opposed to click
.var formEl = $("#jquerytypetext")
var textfield = $("#textfield")
var putItemshere = $("#jquerytextformlist")
function typetextformSubmit(event) {
event.preventDefault();
var newItem = (textfield.val());
textfield.val("");
if (!newItem) {return;}// Prevents blank text from being entered.
var newItemEl = $("<li>");
newItemEl.text(newItem);
newItemEl.addClass("toremove")
putItemshere.append(newItemEl);
}
formEl.on("submit", typetextformSubmit)
element.on("event type", function)
- this is the equivalent to vanilla JS element.addEventListener("event type", function)
.EDparentEl.on("click", ".delete-item-btn", removeBtnED)
DelItemBtn.on("click", removeBtnDefault)
.this
refers to its parent object/element. If it inside a nested function (a function inside another function) it'll return the window
object as it cannot see a parent object - it defaults to the window.<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
.sortable()
function applied to them,dayjs().format(format)
, where the format can be obtained here. Writing out dayjs().format(`[The time is] HH:mm [and the date is] DD-MM-YYYY`)
would give:
.dayjs(inputDate).format("newFormat")
. The following code will switch today's date from shorthand to fully written out.
dayjs(date1).diff(dayjs(date2))
, by default it returns the difference in milliseconds. You can also calculate in different units (e.g. days, weeks, months) by incuding it as the second argument. Note that the default behaviour does not include partial weeks in its calculation - this can be changed by including true
as the third argument.
today.diff(dayjs("2024-01-01"), "days")
dayjs().diff(dayjs("2023-06-31"), "weeks", true)
.fetch(queryURL)
method, the data can be retrieved from the server API. It will come in a .json
file format (or an .xml
).
fetch(queryURL)
.then(function (response) {
return response.json();
}).then(function (data){
what you want to do with the data;
});
fetch
gets data from an external site, it is asynchronous. This means the response from fetch
won't necessarily arrive before other lines of JavaScript are run.
fetch("https://pokeapi.co/api/v2/pokemon/pikachu/")
.then(function (response) {
return response.json();
}).then(function (data){
pokename.text(data.species.name)
pokeimg.attr("src", data.sprites.front_default)
});
queryURL
, e.g. fetch("https://api.giphy.com/v1/gifs/trending?api_key=api key")
.var functionName = function(parameter1, parameter2){expressions}
can be swapped with var functionName = (parameter1, parameter2) => {expressions}
.()
can be omitted like so: var functionName = parameter => {expressions}
.{}
can be omitted like so: var functionName = parameter => expression
. If the purpose of the function is to just return
a value, this can be taken one step further, and return
can be removed altogther, e.g. var multiplyNums = (a,b) => a*b
- here there is no need to type return a*b
.this
keyword to the object it's created inside of. As a result avoid using arrow functions for object methods and instead use a default function.this
keyword represented the object that called the function, which could be the window, the document, a button or whatever. With arrow functions, the this
keyword always represents the object that defined the arrow function.?
which takes in three parameters: condition ? expression if condition is true : expression if condition is false
, e.g. console.log(1 == 1 ? "True" : "False")
would print True
.const
as much as possible, and let
in the case of loops and reassignment. Generally, var
can be avoided outside of legacy code.const
is an array, values can be pushed to it - it can be added onto, just not redefined. const
means constant reference, not constant value.const
can be modified, they cannot be reassigned.const
and let
are always scoped to a block of code, they no longer exist outside of them.let
will not leak outside of a loop or function.while
loops, values created inside also exist outside of the loop..foreach()
loop is a functional way of iterating through an array without using a for
loop, its syntax is arrayName.foreach((input element) => expression)
..filter()
returns a new array based on the filter options. e.g. const newArrayName = arrayName.filter((input element) => expression)
. e.g.:
const moviePatrons = [
{ name: "Tom", age: 16 },
{ name: "Ashley", age: 31 },
{ name: "Sarah", age: 18 },
{ name: "Alvin", age: 22 },
{ name: "Cherie", age: 14 },
{ name: "Malcolm", age: 15 }
];
const canWatchRatedR = moviePatrons.filter((patron) => patron.age > 17);
.map()
which returns a brand new array by applying actions to all the elements of a previous array. It's syntax is const newArrayName = arrayName.map((input element) => expression)
It differs from foreach
as it creates a new array with the new values, rather than affecting the original array. e.g.:
const array1 = [1, 4, 9, 16];
const array2 = array1.map((number) => number*2);
console.log(array1);
console.log(array2);
pwd
inside the VSCode terminal will show the current path.node filename.js
in the terminal to run a JavaScript file with node.setTimeout
is a property of the window
object. In node, it belongs to a special timeout
objectconsole.log(process.argv);
returns an array of command line arguments. Those items can be accessed via index number, e.g. console.log(process.argv[2])
. This just allows you to get inputs from what is entered into the command line, if you wanted to use that in the code (for example to verify user input).require()
, node can pull in other packages similar to how a CDN link works.package.json
by running npm init -y
in the VSCode terminal. (Side note: In the package.json
you can create custom scripts to essentially create shortcuts for large lines you want to put in the terminal.)package.json
is created, the third party packages can be installed with npm i packagename@^version
. Packages can be found on npmjs.com, e.g. Inquirer which would be installed with npm i inquirer@^8.0.0
.node_modules
folder.const packageName = require("packageName");
, e.g. const inquirer = require("inquirer");
fs
is a Node standard library package for reading and writing files. Putting const fs = require("fs");
in the JS file adds it..readFile("filename", "encoding", (error, data) => ...)
allows you to use an if-else statement or a ternary operator to print either the error or the data, in the following example:
fs.readFile('data.csv', 'utf8', (error, data) =>
error ? console.error(error) : console.log(data)
);
"utf8"
encodes the raw buffer data in human-readable format.
.writeFile("filename", "input", (error) => ...)
allows you to write data to a file. The full syntax is:
fs.writeFile('log.txt', process.argv[2], (error) =>
error ? console.error(err) : console.log('Success!')
);
error ? ...
line is using the ternary operator.module.exports
is an object we use to store variables or methods that other JS files can access. There can only be one of thse per JS file. Its syntax is:
module.exports = {
keyName: variable/method from the file,
keyName: variable/method from the file,
};
require("filepath")
in the other to receive them. This sets the variables/methods you exported into a custom variable in this new JS file, e.g.:
const objectName = require("filepath");
rest
operator allows you to not specify the number of input parameters to a function. Its syntax is function functionName(...name)
, where name
refers to the name of the array of input parameters. e.g.:
function add(...nums){
let sum = 0;
for (const num of nums) {
sum += num
}
return sum
}
add
function is run with. The inputs are listed as an array, so running add(1,2,3,4,5)
would have nums
return as [1,2,3,4,5]
, and the function add
would return 1+2+3+4+5 or 15
.
spread
operator is a way to combine two different arrays, instead of nesting one inside another. You would use it as const arrayOne = [...arrayTwo, "example value"]
, e.g.:
const fruits = ["apple", "banana", "orange"];
const foods = [...fruits, "potato", "carrot", "lettuce"];
fruits
inside the foods
array too.
spread
operator can also be used to add values to a new version of an object (or merge two objects). For example if you had an object with set values already, and wanted to add a few already-defined variables to it without using objectName.newKey = value
, e.g.:
const room = {
height: 200,
depth: 400,
chairs: 3,
};
const desks = 3;
const lights = 2;
const painted = "yes";
const roomData = {desks, lights, painted, ...room}
const roomData = {
height: 200,
depth: 400,
chairs: 3,
desks: 3,
lights: 2,
painted: "yes",
};
reduce
method iterates through all values of an array and "reduces" them into a single value. It works in a similar way to the forEach()
method, but collects all the iterated results into one value. Its syntax is .reduce(function, initialValue)
, where the initial value
is an initial value to start from, if left blank defaults to the first item in the array (index 0). The function
must refer to an accumulator
value and a currentValue
value as its input paramters. e.g.:
const nums = [1, 4, 7];
const numsTotal = nums.reduce((accumulator, currentValue) => {
accumulator + currentValue;
},0)
12
. The function is written directly into the reduce
arguments in this example.
const variableName = objectName.keyName
however many times for each property within the object.const {keyName: optionalVariableName, key2Name: optionalVariable2Name} = objectName
. It then defines a new const
as keyName
with the value objectName.keyName
and likewise for key2Name
.const jaime = {
name: 'Jaime Lannister',
};
const { name: jaimeName } = jaime;// A new variable "jaimename" is defined here with the value "jaime.name"
console.log(jaimeName); // prints "Jaime Lannister"
const [a, b, c] = arrayName
.const betterLogCharacter = ({ name, parents }) =>
console.log(`${name}'s parents are: ${parents[0]} and ${parents[1]}.`);
(object)
(object) as the function's input parameter, it has been destructured to {name, parents}
i.e. the function is now searching for input parameters matching object.name
and object.parents
.
function ConstructorName(parameters) {
this.keyName = value;
this.functionName = function(){}
}
const objectName = new ConstructorName(parameters)
..prototype
..prototype
has methods and properties attached to it, but the methods declared on the prototype are declared once and memory is allocated for them once, despite all objects (that are made from it) having access to them..forEach()
, .toLowercase()
or .push()
- which are available to all arrays, strings and arrays universally through the .prototype
..prototype
to be accessed wherever, e.g.:
Movie.prototype.logInfo = function() {
console.log(`${this.title} was released in ${this.releaseYear}`);
};
const theShining = new Movie("The Shining ", 1980)
theShining.logInfo();
npm install jest
create the JavaScript file, and then create a JSfileName.test.js
to accompany it. Then add this code to the package.json
:
{
"scripts": {
"test": "jest"
}
}
describe("testName", () => {
it("describe what the test should do", () => {
// ARRANGE
const initialValue = initialValue;
const expectedResult = expectedResult;
// ACT
const actualResult = new Constructor().method(initialValue);
// ASSERT
expect(actualResult).toEqual(expectedResult);
});
});
npm run test
.class ClassName {
constructor(parameters) {
this.keyName = value;
functionName() {}
}
}
class Shape {
constructor(area, perimeter) {
this.area = area;
this.perimeter = perimeter;
}
printInfo() {
console.log(`Area: ${this.area}`);
console.log(`Perimeter: ${this.perimeter}`);
}
}
const shape = new Shape(25, 25);
shape.printInfo();
Area: 25, Perimeter: 25
.
const objectName = new ClassName(parameters)
.class Rectangle extends Shape {
constructor(sideA, sideB) {
const area = sideA * sideB;
const perimeter = sideA * 2 + sideB * 2;
super(area, perimeter);
this.sideA = sideA;
this.sideB = sideB;
}
}
super()
is how parameters are passed along from the subclass to the parent class. extends Class
is how you set up a subclass.npm create vite@latest fileName -- --template react
.npm install
followed by npm run dev
.npm run dev
starts the live server for a react project and ctrl + c
will kill the server.function HelloReact() {
return <p>Hello World!</p>;
}
return <HelloReact />;
which is equivalent to vanilla JS's HelloReact()
- i.e. just calling a previously defined function.<>
tags.className
rather than class
.{}
. It works similarly to the template literal format except there is no dollar sign..jsx
file for each component, or in a corresponding stylesheet imported into each component's page via import "../styles/Header.css";
.const styles = {
card: {
margin: 20,
background: "#e8eaf6"
},
heading: {
background: "#3f51b5",
minHeight: 50,
lineHeight: 3.5,
fontSize: "1.2rem",
color: "white",
padding: "0 20px"
},
content: {
padding: 20
}
};
const cardStyles = {}
instead of nesting the card object within the styles object.
font-size
) are switched to camel case: fontSize
.npm i --save bootstrap @popperjs/core
in the terminal, and import "bootstrap/dist/css/bootstrap.min.css";
and import * as bootstrap from "bootstrap"
in the main.jsx
file.function Alert(props) {
return (
<div className={`alert alert-${props.type || "success"}`} role="alert">
props.type
returns as false the default value will be success which will make alert-success
show.
{props.children}
</div>
);
}
App.jsx
, where different values can be passed into it depending on context, e.g.:
function App() {
return <Alert type="danger">Invalid user id or password;
}
{
"type": "danger",
"children": "Invalid user id or password"
}
children
is always what is between the opening and closing tags of the component.
useState
hook offers a way for components to manage state directly, eliminating the need for data retrieval through prop drilling.const [state, setState] = React.useState(initialValue)
import React, { useState } from 'react';
which imports it deconstructed in that line so you can later use useState
in place of React.useState
.const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
};
state
of "count", a setState
of "setCount" and an initial value of "0". The function defined below makes it so that every iteration the new value is the former value plus 1....
) operator to not entirely redefine the object upon updating the state, e.g.:
const [ houseState, setHouseState ] = React.useState({
doors: 4,
windows: 23,
occupants: 5,
name: "House",
})
setHouseState({ ...houseState, doors: 7 })
.jsx
component is re-rendered.useState
HookuseEffect
HookuseEffect
can be imported the same way as useState or used with React.useEffect
.useEffect
takes two arguments, first a callback function and second an array of dependencies. When the component re-renders, useEffect
re-runs its callback function if any dependency values change.props.name
is specified, useEffect
runs once on initial page render, and subsequently whenever props.name
changes:
useEffect(() => {
callback function
}, [props.name]);
useEffect
will only run the first time the component renders.
useEffect(() => {
callback function
}, []);
use
like useState
or useEffect
.function usehookName() {
const [ state, setState ] = useState();
// Code that performs the purpose of the hook.
return setState
}
function useCounter() {
const [ count, setCount ] = useState(0)
const increment = () => setCount(count + 1)
return [ count, increment]
function CounterComponent() {
const [ count, increment ] = useCounter()
return (
<>
<p>Count: {count}</p>
<button onClick={increment}>Add 1</button>
</>
)
}
useState()
therefore has an object as the default value, e.g.:
const [formData, setFormData] = useState({
firstName: "",
lastName: "",
});
formData.firstName
and formData.lastName
, that can be updated based on user input (once a function is created). The values for the two keys are blank because we don't need an actual default value.
value
, name
, and onChange
function, as well as a type
and optionally placeholder
.
<input
value={formData.firstName}
name="firstName"
onChange={handleInputChange}
type="text"
placeholder="First Name"
/>
const handleInputChange = (e) => {
const { name, value } = event.target
setFormData({
...formData,
[name]: value,
})
}
e
or event
. Console logging e.target
would return the element that the function is attached to, i.e. the input field. We want to access the name and value of that element specifically though, so we need event.target.name
and event.target.value
. When destructured, that displays as below.event.target.name
and event.target.value
consts above. So now insert them into the setFormData()
.[name]
.formData
state, then updates it (while keeping the previous data - thanks to the spread operator), with the value of the same input field.formData
.event.preventDefault()
even in React to prevent the form from refreshing the page.fetch
function a little by removing the need to parse the .json
data received. It needs to be installed with npm i axios
and imported with import axios from "axios";
as normal with a NPM package.
API.js
file inside a utils
folder in the react project. Inside that the function can be exported as an object method as shown below:const baseURL = API Base URL;
const apiKey = API Key;
export default {
search: function(query) {
return axios.get(baseURL + query + apiKey)
},
}
.then
to handle the received data asynchronously.
API(or whichever file the method was exported from).search(query)
.then((res) => whatever you want to do with the data)
.catch((err) => console.log(err));
npm i react-router-dom
and then add import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
to App.jsx
.
function App() {
return(
<Router>
<elementName>
// [1]
<Routes>// [2]
<Route path="path" element={elementName} />// [3]
<Route path="path/*" element={elementName} />// [4]
Routes
component.Routes
component.element={<Home />}
./*
inside the path.NavLink
and Link
, which can be imported via import { NavLink, Link } from "react-router-dom";
inside a JSX file. These replace anchor tags for navigating within the same website. If you wanted to navigate to another site, then a regular anchor tab could be used.NavLink
and Link
is that NavLink
tracks the active page, which is useful for styling, whereas Link
doesn't. The easiest way to do this is to use a ternary statement in the className
of a NavLink
element, e.g.:
<NavLink
to="path"
className={({isActive}) =>
isActive ? "nav-link active" : "nav-link"
}
className
as (in this example) nav-link active
if isActive
returns truthy, or just nav-link
if falsy.
Routes
on the homepage, and to use NavLink
or Link
anywhere else within the project.