JavaScript
[TypeScript]
Variables
It’s all dynamically typed!
let - variable values
const - constant values
var** **- don’t use this anymore, use let instead
If you want to use static typing, look at TypeScript
Functions
function callMe(name) {
console.log(name);
}
can also be stored in a variable:
const callMe = function(name) {
console.log(name);
}
could be written as an arrow function:
const callMe = (name) => {
console.log(name);
}
When it has no arguments, use empty braces
const callMe = () => {
console.log("Blah");
}
Return a value
const returnMe = name => { // can omit braces if exactly one argument
return name;
}
If an arrow function does nothing but returns a value, it can be shortened to:
const returnMe = name => name;
Async Functions
// ASYNC FUNCTION
async function callMe(name) {
console.log(name);
}
// ASYNC ARROW FUNCTION
const callMe = async (name) => {
console.log(name);
}
await callMe('Markus');
Strings ⌨️
const string1 = "A string primitive";
const string2 = 'Also a string primitive';
const string3 = `Yet another string primitive`;
const string4 = new String("A String object");
'cat'.charAt(1) // gives value "a"
'cat'[1] // gives value "a"
Template strings (use backtick ```) - allow you to use variables inside ${}
const name = 'Markus';
console.log(`Hello, ${name}`); // prints: Hello, Markus
Equality
1 == 1; // true
'1' == 1; // true
0 == false; // true
0 != false; // false
Strict equality
1 === 1; // true
'1' === 1; // false
0 === false; // false
0 !== false; // true
Loops and iteration ⚙️
for
for(let i = 0; i < 10; i++) {
console.log(i);
}
for .. in, for .. of
const arr = [3, 5, 7];
arr.foo = 'hello';
// for .. in - gives you keys
for (const i in arr) {
console.log(i); // logs: 0, 1, 2, foo
}
// for .. of - gives you values (but only of iterable objects - notice how it leaves out 'hello'!)
for (const i of arr) {
console.log(i); // logs: 3, 5, 7
}
Also note that Array has a forEach()!
const fruits = ["apple", "orange", "cherry"];
fruits.forEach((fruit) => console.log(fruit)); // logs: apple, orange, cherry
while
let i = 0;
while(i < 10) {
console.log(i);
i++;
}
do while
let i = 0;
do {
console.log(i);
i++;
} while(i < 10);
break, continue
let i = 0;
while (i < 6) {
if (i === 5) break; // exit
i = i + 1;
if(i === 3) continue;
console.log(i);
}
// output: 1, 2, 4, 5
Modules 📦
To access functionality in another file you need to export it from File A and import it into File B
// FILE A
export default const returnMe; //export as default (unnamed)
export const someData = 123; //named export
export const someFunction = () => { console.log('blah'); };
//FILE B
import whatever from './path/to/file.js'; //import default export and give it whatever name you want in the process
import { someData, someFunction } from './path/to/file.js'; //import named exports
import whatever, { someData } from './path/to/file.js'; //import default and named exports
import * as upToYou from './path/to/file.js'; //import all named exports at once
console.log(upToYou.someData);
Objects
An object is a collection of properties (a property is an association between a name/key and a value - value can be a function!)
const myCar = new Object();
myCar.make = 'Tesla';
myCar.model = 'Model 3';
myCar.year = 2022;
But usually you’d write this as an object initializer:
const myCar = {
make: 'Tesla',
model: 'Model 3',
year: 2022
};
Unassigned properties of an object are undefined (and not null)
An Object’s properties can contain other Objects, as well as functions:
const myCar = {
color: 'red',
wheels: 4,
engine: { // <-- Object
type: 'electric',
kW: 336,
torque: 639
},
logPower() { // <-- method
console.log(this.engine.kW); // Note the use of `this` to refer to the current object
}
}
Properties can be identifiers, numbers or strings:
const obj = {
property1: value1,
2: value2,
'property n': value3
};
Properties can be accessed in different ways:
myCar.model = 'Model Y';
myCar['model'] = 'Cybertruck';
const key = 'model';
myCar[key] = 'Model 2; // anything that converts to a string can be a key!
You can also create objects through a constructor function
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const car1 = new Car('Tesla', 'Model 3', 2022);
const car2 = new Car('Nissan', 'X-Trail', 2014);
All objects inherit from at least one other object. The object being inherited from is known as the prototype.
If you want to learn a lot more about the weirdness of prototypes → read The Joy of JavaScript
You can add properties to previously defined object types through the **prototype** property.
Car.prototype.color = null; // add color property to all objects of type Car
car1.color = 'black'; // assign color black only to the object car1
Object.create() can be useful because it allows you to choose the prototype object for the object you create.
const Animal = {
type: 'Invertebrates', // Default value of property
displayType() { // Method to display the type of Animal
console.log(this.type);
}
};
const animal1 = Object.create(Animal);
animal1.displayType(); // Output: Invertebrates
const fish = Object.create(Animal);
fish.type = 'Fishes';
fish.displayType(); // Output: Fishes
Duplicating Objects
let nData = { ...data }; // only a shallow copy
let nData = structuredClone(data); // deep clone, yeah!
Classes
First and foremost: You don’t really need classes in JS. You can do everything and more with Objects and prototypes.
Did you know? Classes were introduced to distract you from the craziness that’s going on under the hood (objects + prototypes).
old syntax:
class Person {
constructor() {
this.name = 'Markus';
}
}
const person = new Person();
console.log(person.name);
New syntax for defining class properties:
class Person {
name = 'Markus;
}
const person = new Person();
console.log(person.name);
Add functions:
class Person {
name = 'Markus';
printName() {
console.log(this.name);
}
}
const person = new Person();
person.printName();
or like this (arrow function has the advantage of the this keyword not changing its reference)
class Person {
name = 'Markus';
printName = () => {
console.log(this.name);
}
}
const person = new Person();
person.printName();
Inheritance
class Human {
species = 'human';
}
class Person extends Human {
name = 'Markus';
printName = () => {
console.log(this.name);
}
}
const person = new Person();
person.printName();
console.log(person.species);
Private fields and methods: #
class Person {
#name = '';
constructor(name) {
this.#name = name;
}
printName = () => {
console.log(this.#name);
}
}
const person = new Person("Markus");
person.printName(); // Markus
//console.log(person.#name); // ERROR
Spread and Rest Operator
3 dots: …
The spread operator allows you to pull elements out of an array (to split the array into a list of its elements.
const oldArray = [1, 2, 3];
const newArray = [...oldArray, 4, 5]; //this is now [1, 2, 3, 4, 5]
Spread operator used on an object:
const oldObject = {
name: 'Cat'
};
const newObject = {
...oldObject,
age: 3
};
// newObject is now { name: 'Cat', age: 3 }
The rest operator allows us to create variadic functions and place any number of arguments into an array (can be used like params int[] args in C#):
const someObject = { a: 1, b: 2, c: 3, d: 4 };
const { a, b, ...otherAttrs } = someObject; // a, b and rest goes into otherAttrs
console.log(otherAttrs); // prints { c: 3, d: 4 }
Destructuring
Allows easy access to values of arrays or objects and assigning them to variables.
const array = [1, 2, 3];
const [a, b] = array;
console.log(a); // prints 1
console.log(b); // prints 2
console.log(array); // prints [1, 2, 3]
Destructuring is very useful when working with function arguments:
Watch how we can change this:
const printName = (personObject) => {
console.log(personObj.name);
}
printName({ name: 'Markus', age: 40 }); // prints 'Markus'
into this:
const printName = ({name}) => {
console.log(name);
}
printName({ name: 'Markus', age: 40 }); // prints 'Markus'
we can even add defaults:
const printName = ({name='Billy', age=12}) => {
console.log( `${name}, ${age}` );
}
printName({ name: 'Markus' }); // prints 'Markus, 12'
printName({}); // prints 'Billy, 12'
printName(); // ERROR
True and False
Truthy values translate to true when evaluated as a Boolean. A value is truthy if it’s not falsy. (Yep, that is the official definition)
Leave a comment