javaScript - Anton-L-GitHub/Learning GitHub Wiki
Test
console.log('Hello World');
Variables
let name = 'Frank';
let age = 55;
let isFemale = false;
let favoritAnimal = undefined;
let selectColor = null; // When we want to clear the value of a variable
Constants
const num = 1;
Arrays
let colors = ['red', 'blue'];
Array functions
const numbers = [3, 4];
numbers.push[5, 6]; // adds elements to the end of array
numbers.unshift[1, 2]; // adds elements to the beginning of array
numbers.splice[0, 5, 6] // adds element to specific position in array
Arrow Functions
Find object in an array of objects
const courses = [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
];
const course = courses.find(course => course.name === 'b');
console.log(course);
Functions
Example 1:
function greet(firstName, lastName) {
console.log('Hello ' + firstName + ' ' + lastName);
}
greet('Peter', 'Pan');
Example 2:
function square(number) {
return number * number;
}
console.log(square(2));
Comparison Operators
let x = 1;
console.log(x === 1); // Equal to
console.log(x !== 1); // Not equal to
=== vs. ==
1 === 1 Strict Equality (Same type and value)
1 == '1' Lose Equality (Same value, doesn't care about the types matching. If they aren't matching the right side will be converted to the same type as the left side)
AND, OR, NOT
AND = &&
OR = ||
NOT = !
Falsy and truthy
Falsy values in JavaScript: undefined, null, 0, false, '', NaN
Anything that is not falsy is truthy
If and switch
If-statements
let role = 'admin';
if (role === 'admin') {
console.log('Admin');
}
else if (role === 'user') {
console.log('User')
}
else
console.log('Unknown')
Switch...case
Compares the value of a variable against other values
let role = 'user';
switch (role) {
case 'admin':
console.log('Admin');
break;
case 'user':
console.log('User');
break;
default:
console.log('Unknown');
}
Ternary Operator / Conditional operator
let points = 110;
let type = points > 100 ? 'gold' : 'silver';
If the points are more than 100 you will get 'gold, otherwise 'silver'
Loops
For-loop
for (let i = 0; i < 5; i++) {
console.log('Hello world')
}
While loop
let i = 0;
while (i <= 5) {
if (i % 2 !== 0) console.log(i);
i++;
}
Do-while loop
Always executes at least once, even if the condition evaluates to false.
let i = 0;
do {
if (i % 2 !== 0) console.log(i);
i++;
} while (i <= 5);
For-in loop
Used when we ex. want to display all the properties of an object. Can also be used to display all the content in a list.
const person = {
name: 'Mosh',
age: 30
};
for (let key in person)
console.log(key, person[key]);
const colors = ['red', 'green', 'blue'];
for (let index in colors)
console.log(index, colors[index]);
For-of loop
Used to iterate over the contents of an array.
const colors = ['red', 'green', 'blue'];
for (let color of colors)
console.log(color);
Iterating an Array with forEach
const numbers = [1, 2, 3];
numbers.forEach(number => console.log(number));
Objects
Object literal
With the object-literal-syntax you create one specific object
Can contain values, methods and other objects
const object
- This object can not be reassigned, it is however possible to add and remove properties and methods
const objectLiteral = {
name: 'Object Objectsson',
location: {
address: 'Object Road',
zip: '12345'
},
isJavaScript: true,
draw: function() {
console.log('draw');
}
};
Object Destructuring
Saving the properties of an object as constants
Change the name of the constant like the example bellow
const dog = {
name: 'rufus',
breed: 'pudel',
owner: 'per persson'
}
const { name, breed, owner: ow } = dog;
// Saving the properties of dog as constants, name is the name of the dog, breed is the breed and so on.
// taking the contents of owner and assigning it to the constant ow
Factory Functions
Returns an object, no need to use the 'new'-keyword when creating an object
Use if you want to create several objects
camelNotation
function factoryFunction(name, address, city) {
return {
name;
address;
city
};
}
let object1 = factoryFunction('Object Objectsson', 'Object road 1', 'Objectville');
Constructor Function
Constructs/creates objects
Must use the 'new'-keyword to be able to use 'this'
'new' creates an empty object, then it will set 'this' to point to the object and finally it will return the object from our constructor function (so when we call theobject.constructor
property it will reference our function)
without 'new', 'this' will point to the global object Window()
Use if you want to create several objects
PascalIsUsed
function ConstructorFunction(name, address, city) {
this.name = name;
this.address = address;
this.city = city;
this.sendMail = function {
console.log('send');
}
}
let object2 = new ConstructorFunction('Object Objectsson', 'Object road 1', 'Objectville');
Constructor Functions vs. Factory Functions
They are equally good
Constructor functions is familiar to developers with previous experience in ex. Java
Classes
New in ES6
Classes in JavaScript are "syntactic sugar" and do not work like classes in ex. Java or C#
They are actually constructor functions
class Animal {
constructor(type, color) {
this.type = type;
this.color = color
}
walk() {
console.log('walk');
}
}
const ani = new Animal('lion', 'beige');
ani.walk();
Static methods
Methods that are not part of an instance of the class, but the class itself
Utility functions (verktyg) that are not tied to a specific object
class Animal {
constructor(typeOfAnimal) {
this.typeOfAnimal = typeOfAnimal;
}
walk() {
console.log('walk');
}
static parse(str) {
const typeOfAnimal = JSON.parse(str).typeOfAnimal;
return new Animal(typeOfAnimal);
}
static makeSound(sound) {
console.log(`Some animals sound like this: ${sound}`);
}
}
const myAnimal = Animal.parse('{"typeOfAnimal": "Kangaroo" }');
console.log(myAnimal);
Objects are dynamic
Additional properties and methods can be added and removed after the object has been created
function Dog(breed) {
this.breed;
}
const myDog = new Dog('pudel');
myDog.name = 'Pelle'; // add new property
delete myDog.breed; // remove property
Private Properties and Methods
Abstraction = Hide properties and methods in object
Instead of setting something as a propery, we can define it as a local variable. This hides it from the outside.
function Flower(name, color) {
this.name = name;
this.color = color;
let season = 'spring'; // since this is a local variable, it can't be changed from the outside (we can also do this with methods)
}
Private Properties and Methods using Symbols
A Symbol() is a function to generate a unique identifier. We use this unique value as the property name of an object instead of a string.
const _owner = Symbol();
const _trix = Symbol();
class Dog {
constructor(name, owner) {
this.name = name;
this[_owner] = owner; // private property
}
[_trix]() {
console.log('Make a secret trick!'); // private method
}
}
const myDog = new Dog('rufus', 'per persson');
Private Properties and Methods using WeakMaps
A WeakMap is a dictionary, where keys are objects and values can be anything. It's called WeakMaps because the keys are weak. If there are no references to these keys, they will be garbage collected.
const _owner = new WeakMap();
const _jump = new WeakMap();
class Dog {
constructor(name, breed, owner) {
this.name = name;
this.breed = breed;
_owner.set(this, owner); // private property // set-method
_jump.set(this, () => {
console.log('jump', this);
});
}
getOwner() {
return _owner.get(this); // get method
}
sitDown() {
_jump.get(this)();
console.log('sit');
}
}
const aDog = new Dog('rufus', 'pudel', 'Peter Persson');
aDog.getOwner();
aDog.sitDown();
Constructor Property
Every object has a property called
constructor
which references the function that was used to construct or create the objectobject.constructor
Value vs. Reference types
Value Types
- Number
- String
- Boolean
- Symbol
- undefined
- null
Reference types
- Object
- Function
- Array
Primitives vs. objects
Primitives are copied by their value
Objects are copied by their reference
Primitives example:
let x = 10;
let y = x;
x = 20;
Object example:
let x = { value. 10 };
let y = x;
x.value = 20;
In the objects example, both x and y are pointing to the same location in memory and therefor getting the same value
Enumerating Properties of an Object
Getting access to all the properties and methods of an object
const circle = {
radius: 1,
draw() {
console.log('draw'):
}
};
Example 1:
for (let key in circle)
console.log(key, circle[key]);
Example 2:
for (let key of Object.keys(circle))
console.log(key);
Example 3:
for (let entry of Object.entries(circle))
console.log(entry);
Check if a given property or method exists in an object
if ('radius' in circle) console.log('yes');
Cloning an Object
const circle = {
radius: 1,
draw() {
console.log('draw');
}
};
Example 1:
const another = Object.assign({}, circle); // Copies all the properties and functions from circle to the new object
Example 2:
const another = { ...circle }; // The spread operator is cleaner
{}
represents an empty object
Garbage Collection
Finds variables and constants that are no longer used. It deallocate the memory that was allocated to them earlier.
Runs in the background
Math Object
Math.random()
Math.round()
Math.max()
Math.min()
String Object
//String primitive
const message = 'hi';
// String object
const another = new String('hi');
Functions
message.length;
message.includes('hi');
message.startsWith('h');
message.endsWith('i');
Code | Output |
---|---|
\0 | NULL |
\' | single quote |
\" | double quote |
\\ | backslash |
\n | new line |
\r | carriage return |
\v | vertical tab |
\t | tab |
Template Literals
Example 1:
const message =
`The message starts on this line,
continues on this line
and ends on this line`;
Use `` to write on several lines
Example 2:
name = 'Emma';
const myMessage =
`Hi ${name}
You look nice today! :)
`
Use ${} to make the message dynamic
How to compare two objects exercise
let address1 = new Address('a', 'b', 'c');
let address2 = new Address('a', 'b', 'c');
console.log(areEqual(address1, address2));
console.log(areSame(address1, address2));
function Address(street, city, zipCode) {
this.street = street;
this.city = city;
this.zipCode = zipCode
}
function areEqual(address1, address2) {
return address1.street === address2.street &&
address1.city === address2.city &&
address1.zipCode === address2.zipCode;
}
function areSame(address1, address2) {
return address1 === address2;
}
Arrays
Find elements in array (Primitive Types)
Type matters
const numbers = [1, 2, 3, 1, 4];
numbers.indexOf(1); // returns the index of the given element
number.lastIndexOf(1); // returns the last index of the given element
numbers.includes(1); // returns true if element exists in the array
Find elements in array (Reference Types)
Call-back function
const courses = [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' }
];
const course = courses.find(function(course) {
return course.name === 'a';
});
Returns the first element that matches the given criteria, otherwise returns undefined
To get the index, usearrayName.findIndex()
Remove elements in array
const numbers = [1, 2, 3, 4];
numbers.pop(); // removes last element in array and returns it
numbers.shift(); // removes first element in array and returns it
numbers.splice(startIndex, numOfElementsToRemove) // removes element somewhere in the middle
numbers.length = 0; // empties an entire array
Combine two arrays
Spread Operator
Lets us add the contents of several arrays plus other elements
const first = [1, 2, 3];
const second = [4, 5, 6];
const combined = [...first, 'abc', ...second, 'def];
Check elements of array
Check if all elements matches our critera with
arrayName.every()
const numbers = [1, 2, 3];
const allPositive = numbers.every(function(value) {
return value >= 0;
});
Check if at least on element in array matches our criteria with
arrayName.some()
const numbers = [1, 2, 3];
const atLeastOnePositive = numbers.some(function(value) {
return value >= 0;
});
Filter the array with arrayName.filter()
Mapping an array
We can map each item in an array to something else, ex. HTML, strings, objects etc.
const numbers = [1, 2, 3, -4];
const items = numbers
.filter(n => n >= 0)
.map(n => ({ value: n }))
Reducing an array
Takes all element in an array into a single value. The value can be a number, a string, an object etc.
const numbers = [1, -1, 2, 3];
const sum = numbers.reduce(
(accumulator, currentValue) => accumulator + currentValue;
);
Functions
Defining a function
Function Declaration
walk();
function walk() {
console.log('walk');
}
- We can call the walk() function before it is defined with hoising, we can not do this with Function Expression
Function Expression
let run = function <optionalName> () {
console.log('run');
};
run();
- Must end with ; when declaring variables
- The variable 'run' references the function
- We can give the function a name or let it be anonymous
Hoisting
- The process of moving function declarations to the top of the file. This is done automatically by the JavaScript engine that is executing the code. This is the reason why we can call functions that are defined using the function declaration syntax before their definition.
walk();
function walk() {
console.log('walk');
}
Arguments
Every function has an object called arguments where the keys are the indexes of the arguments
We can use this to iterate through the values
The Rest Operator
Lets us pass a varying number of arguments to a function and puts them in an array
Remember, the rest parameter has to be the last one in function
function sum(...args) {
console.log(args);
}
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Default Parameters
function bank(loan, rate = 3.5, years = 5) {
return loan * rate / 100 * years
}
This let us either specify the rate and years or use the defaults
Remember to put the parameters with defaults at the end
Getters & Setters
Getters to access properties in objects
Setters to change properties in objects
Getters & Setters in Object Literals
const person = {
firstname: 'Mosh',
lastName: 'Hamedani',
get fullName() {
return `${person.firstname} ${person.lastName}`
},
set fullName(input) {
const parts = input.split(' ');
this.firstname = parts[0];
this.lastName = parts[1];
}
};
person.fullName = 'John Smith';
console.log(person);
Getters & Setters in Constructor Functions
function Address(street, city, zipCode) {
this.street = street;
this.city = city;
this.zipCode = zipCode;
let buildingType = 'apartment'; // private variable
Object.defineProperty(this, 'buildingType', {
get: function() {
return buildingType;
},
set: function(value) {
if (typeof(value) === 'string')
buildingType = value;
}
});
};
let myAddress = new Address('a', 'b', 12345);
console.log(myAddress.buildingType); // get buildingType
myAddress.buildingType = 'house'; // set buildingType
Getters and Setters in Classes
const _owner = new WeakMap(); // private property
class Dog {
constructor(name, breed, owner) {
this.name = name;
this.breed = breed;
_owner.set(this, owner);
}
get getOwner() { // Getter
return _owner.get(this);
}
set setOwner(value) { // Setter
if (typeof(value) === 'string')
_owner.set(this, value);
}
}
const aDog = new Dog('rufus', 'pudel', 'Peter Persson');
console.log(aDog.getOwner);
aDog.setOwner = 'Anna Andersson';
Try and Catch
- Error handling
const person = {
firstname: 'Mosh',
lastName: 'Hamedani',
set fullName(input) {
if (typeof input !== 'string')
throw new Error('Input is not a string'); // thows an exception
const parts = input.split(' ');
if (parts.length !== 2)
throw new Error('Enter a first and last name');
this.firstname = parts[0];
this.lastName = parts[1];
}
};
try {
person.fullName = '';
}
catch (e) {
console.log(e);
}
console.log(person);
Let vs. Var
- Main difference is scoping rules. Variables declared by var keyword are scoped to the immediate function body (hence the function scope) while let variables are scoped to the immediate enclosing block denoted by { } (hence the block scope).
OOP
- Object Oriented Programming
- Encapsulation
- Groups related variables and functions together so we can reduce complexity and increase reusability
- Abstraction
- Complexity is hidden, only shows the essentials. Reduces complexity and isolates the impact of changes
- Inheritance
- Eliminates redundant code
- Polymorphism
- Refactor ugly switch/case statements
Inheritance
Enables an object to take on properties and methods of another object
Classical vs. Prototypical Inheritance
- A prototype is like a parent of another object
Multilevel Inheritance
- Object A derives from Object B that derives from Object C
Example of inheritance
- A Dog-object inherits from an Animal-object
Prototypes & How to inherit from another object & Super Constructors
A prototype is like a parent of another object. An object inherits from the prototype.
We have a method for creating an object with a given prototype:
function Animal(sound, color) {
this.sound = sound;
this.color = color;
}
function Dog(breed, sound, color) {
Animal.call(this, sound, color); // this is how you call the SUPER CONSTRUCTOR
this.breed = breed;
}
function Cat(food, sound, color) {
Animal.call(this, sound, color)
this.food = food;
}
// Intermediate Function Inheritance
function extend(Child, Parent) {
Child.prototype = Object.create(Parent.prototype); // returns an object that inherits from the parent
Child.prototype.constructor = Child; // when changing the prototype of an object, you should also reset the constructor (otherwise we can't create ex. the dog-objects based on it's constructor, we will get an animal-object instead)
}
extend(Dog, Animal);
extend(Cat, Animal);
let myDog = new Dog('pudel', 'woof', 'white');
let myCat = new Cat('meat', 'mjauu', 'black');
console.log(myDog);
console.log(myCat);
Inheritance in Classes
Easy! Use extends
class Plant {
constructor(typeOfPlant) {
this.typeOfPlant = typeOfPlant;
}
grow() {
console.log('grow');
}
}
class SunFlower extends Plant { // extends
constructor(color, season, typeOfPlant) {
super(typeOfPlant); // super
this.color = color;
this.season = season;
}
bloom() {
console.log('bloom');
}
}
const myGarden = new SunFlower('yellow', 'summer', 'flower');
Method Overriding
Override a method that is defined in the parent
We do this by redefining the method in the child-object
function extend(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
}
function Animal() {
}
Animal.prototype.duplicate = function() {
console.log('duplicate');
}
function Dog() {
}
extend(Dog, Animal);
// must place this AFTER we extend it
Dog.prototype.duplicate = function() {
console.log('duplicate dog');
}
let myDog = new Dog();
Method Overriding in Classes
class Plant {
constructor(typeOfPlant) {
this.typeOfPlant = typeOfPlant;
}
grow() {
return 'grow';
}
}
class SunFlower extends Plant {
constructor(color, season, typeOfPlant) {
super(typeOfPlant);
super.grow();
this.color = color;
this.season = season;
}
grow() {
super.grow(); // super
return 'sunflower grow'; // Overriding
}
}
const myGarden = new SunFlower('yellow', 'summer', 'flower');
console.log(myGarden.grow());
Polymorphism
Provides a way to call the same method (from a parent-object) on different child-objects and also changing it depending on the child-object.
The Dog and Cat objects will provide different implementations of a method in Animal, this is called "polymorphism"
"Use Strict"
use strict
is set at the beginning of a script or function to indicate that the code should be executed in strict mode
In strict mode you can not use undeclared variables, if mistyping a variable name you will get an error and not a new variable, etc.
Changes some silent errors to throw errors, fixes mistakes that make it difficult for JS engines to perform optimizations (strict mode code can sometimes be made to run faster than identical code that's not strict mode), it also prohibits some syntax likely to be defined in future versions.
Strict mode for entire scripts:
'use strict'
let message = 'Hi! I'm a strict mode script!';
Strict mode for functions
function strict() {
'use strict';
return 'I'm a strict function'
}
Strict mode for modules
function strict() {
// because this is a module, I'm strict by default
}
export default strict;
Modules
Programs are divided into modules, just like books are divided into chapters.
CommonJSModules
Cohesion = Things that are highly related go together
Filecat.js
:
const _name = new WeakMap();
class Cat {
constructor(name) {
_name.set(this, name);
}
getName() {
console.log(`The cats name is ${_name.get(this)}`)
}
}
module.exports = Cat; // export cat-module
File
index.js
const Cat = require('./cat'); // require() to import the cat-module
const myCat = new Cat('misse');
myCat.getName();
ES6 Modules
File
cat.js
:
const _name = new WeakMap();
export class Cat { // Cat will be private if we don't export it (WeakMap will still be private even if we export Cat)
constructor(name) {
_name.set(this, name);
}
getName() {
console.log(`The cats name is ${_name.get(this)}`)
}
}
File
index.js
:
import {Cat} from './cat.js';
const myCat = new Cat('misse');
myCat.getName();
ES6 Tooling
Only needed when building browser applications
Transpiler
- Translator + Compilor
- Converts JS-code to code that all browsers can understand
- Ex. Babel
Bundler
- Combines all our JS-files into a single file, which is called a bundle
Ex. Webpack