JavaScript

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

Your contact detail is only visible to me. Comments are approved by hand.