const name = "David";
const school = "General Assembly";
console.log(`Hello my name is ${name} and I am a student at ${school}.`); // "Hello my name is David and I am a student at General Assembly."
const a = 123;
console.log(a.toString()); // '123'
Convert decimal to binary using .toString(2)
const num = 4;
console.log(num.toString(2)); // '100'
const alphabets = "abcdefghijklmnopqrstuvwxyz";
console.log(alphabets.length); // 26
// indexing a string
console.log(alphabets[0]); // a
console.log(alphabets[25]); // z
console.log(String.fromCharCode(97)); // a
console.log(String.fromCharCode(65, 66, 67)); // ABC
console.log("a".charCodeAt()); // 97
console.log("HELLO".charCodeAt()); // 72 (if index is not a number, it defaults to 0)
console.log("HELLO".charCodeAt(1)); // 69 (Char code of index 1 - 'E')
Compares a string against a given string Returns: -1 for comes before 0 for the same 1 for comes after
console.log("10".localeCompare("100")); // -1
console.log("20".localeCompare("20")); // 0
console.log("2".localeCompare("1000")); // 1
console.log("goodbye".localeCompare("hello")); // -1 ('g' comes before 'h');
const str = "foobar";
console.log(str.repeat(3)); // foobarfoobarfoobar
// NOTE: this is commonly used with a regular expression (regex)
const str = "hello world";
console.log(str.replace("hello", "goodbye")); // goodbye world
const ga = "general assembly";
console.log(ga.replace(/e/g, "3")); // g3n3ral ass3mbly (use of regex to select all 'e')
const sentence = "are vowels important?";
console.log(sentence.replace(/[aeiou]/g, "")); // r vwls mprtnt?
const sentence = "hello my friend";
console.log(sentence.indexOf("my")); // 6
console.log(sentence.indexOf("h")); // 0
console.log(sentence.indexOf("hello")); // 0
const first = sentence.indexOf("e");
console.log(first); // 1
console.log(sentence.indexOf("e", first + 1)); // 12 (use this to find the next index of)
console.log(sentence.indexOf("waddup")); // -1
const sentence = "hello David, my friend";
console.log(sentence.lastIndexOf("D")); // 6
console.log(sentence.indexOf("d")); // 10
console.log(sentence.lastIndexOf("d")); // 21
console.log(sentence.lastIndexOf("e")); // 19
console.log(sentence.lastIndexOf("l")); // 3
console.log(sentence.lastIndexOf("l", 2)); // 2 (only searching from index 0 to index 2 of the string - 'hel')
console.log(sentence.lastIndexOf("l", 1)); // -1 (only searching from index 0 to index 1 of the string - 'he')
// Removes whitespace from both ends of the string
const greeting = " Hello world! ";
console.log(greeting.trim()); // Hello world!
const alphabets = "abcdefghijklmnopqrstuvwxyz";
console.log(alphabets.slice()); // abcdefghijklmnopqrstuvwxyz
console.log(alphabets.slice(3)); // defghijklmnopqrstuvwxyz
console.log(alphabets.slice(3, 7)); // defg (index 3 up to but not including 7)
console.log(alphabets.slice(-3)); // xyz (counting from the end of the string)
console.log(alphabets.slice(-10, -4)); // qrstuv
const str = "hello world";
console.log(str.split()); // ['hello world']
console.log(str.split("")); // ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
console.log(str.split(" ")); // ['hello', 'world']
console.log(str.split("e")); // ['h', 'llo world']
console.log(str.split("l")); // ['he', '', 'o wor', 'd']
console.log(str.split("", 4)); // ['h', 'e', 'l', 'l'] (returns the first 4 splits)
console.log("WADDUP BRO".toLowerCase()); // waddup bro
console.log("hello world".toUpperCase()); // HELLO WORLD
Returns an array of strings that match the regular expression
const randomString =
"the123quick456brown789fox!@#jumped$%^over&*(the)_+lazy{}|dog";
const onlyWords = randomString.match(/[a-z]+/g);
console.log(onlyWords);
// ['the', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy','dog']
console.log(onlyWords.join(" ")); // 'the quick brown fox jumped over the lazy dog'
let a = 12; // let instead of const as they will not work with const
a += 3; // 15
// a = a + 3
a -= 3; // 9
// a = a - 3
a *= 3; // 36
// a = a * 3
a /= 3; // 4
// a = a / 3
let i = 1; // let instead of const as they will not work with const
console.log(i++); // 1
console.log(i); // 2
let i = 1; // let instead of const as they will not work with const
console.log(++i); // 2
console.log(i); // 2
Returns a string representation of the number rounded to n decimal places
(12345.6789).toFixed(3); // "12345.679"
Returns a string representation of the number rounded to n digits
(12345.6789).toPrecision(6); // "12345.7"
Due to the double-precision floating-point format, using a number LARGER THAN 9007199254740991 may result in loss of precision
const x = Number.MAX_SAFE_INTEGER + 1;
const y = Number.MAX_SAFE_INTEGER + 2;
console.log(x === y); // true
Due to the double-precision floating-point format, using a number SMALLER THAN -9007199254740991 may result in loss of precision
const x = Number.MIN_SAFE_INTEGER - 1;
const y = Number.MIN_SAFE_INTEGER - 2;
console.log(x === y); // true
Not going into detail as these are pretty self explanatory
Math.random(); // returns a floating point number between 0 to 1 (inclusive of 0, but not 1)
Math.floor(input); // returns the largest integer less than or equal to a given number
Math.ceil(input); // returns the smallest integer greater than or equal to a given number
Math.trunc(input); // returns the integer part of a number by removing the decimals
Math.round(input); // returns the value of a number rounded to the nearest integer
// 4 ** 2 = 16 use this instead (ES6)
Math.pow(base, exponent); // returns the base raised to the exponent e.g. Math.pow(4, 2) = 16
Math.sqrt(input); // returns the square root of a number
Math.cbrt(input); // returns the cube root of a number
Math.PI; // returns 3.141592653589793
Javascript will attempt to coerce an unexpected value type to the expected type
Does not work with addition as it leads to concatenation
console.log("6" + "9"); // '69' (string)
console.log("10" - "7"); // 3 (number)
console.log("3" * "3"); // 9 (number)
console.log("10" / "2"); // 5 (number)
NaN is a special value, it is never equal to another NaN value
Comparing/equating anything with NaN will result in false
console.log(NaN == NaN); // false
console.log("hello" == NaN); // false
console.log(["this", "is", "an", "array"] == NaN); // false
console.log({ name: "ben", age: 20 } == NaN); // false
console.log(NaN != NaN); // true
To test for NaN, use isNaN()
console.log(isNaN("hello")); // true
console.log(isNaN(["this", "is", "an", "array"])); // true
console.log(isNaN({ name: "ben", age: 20 })); // true
- false
- undefined
- null
- 0
- ''
- NaN
- true
- {} (empty object)
- [] (empty array)
- 69
- -1
- 1
- 'hello'
const arr = [1, 2, 3, 4, 5];
// no need to compare using while(arr.length != 0)
while (arr.length) {
console.log(arr.pop());
}
// 5
// 4
// 3
// 2
// 1
console.log(arr); // []
Both || and && evaluate from left to right
Using ||
if left is truthy, left will be returned
if left is falsy, right will be returned
const people = [
{ name: "jerry", occupation: "teacher" },
{ name: "sandra", occupation: "dentist" },
{ name: "sloth" }
];
for (let i of people) {
console.log(`${i.name}: ${i.occupation || "jobless"}`);
}
// jerry: teacher
// sandra: dentist
// sloth: jobless
Using &&
if left is truthy, right will be returned
if left is falsy, left will be returned
let online = true;
const getData = () => {
console.log("SENDING REQUEST...");
console.log("STATUS 200 RECEIVED");
};
if (online) {
getData();
}
// above if statement can be refactored to
online && getData();
let a = null;
let b;
console.log(a); // null
console.log(b); // undefined
typeof a; // 'object'
typeof b; // 'undefined'
a === b; // false
a == b; // true
Constant variables have to be explicitly assigned a value
const a = null;
const b = undefined;
const c; // ERROR: Missing initializer in const declaration
console.log(a); // null
console.log(b); // undefined
console.log(c); // ReferenceError: c is not defined
const arr = [1, 2, 3, 4, 5];
const [first, second, third, ...rest] = arr;
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [4, 5]
Swapping variables
let a = 2;
let b = 5;
[a, b] = [b, a];
console.log(a); // 5
console.log(b); // 2
Array.isArray([1, 2, 3]); // true
Array.isArray({ foo: 123 }); // false
Array.isArray("foobar"); // false
Array.isArray(undefined); // false
const arr = ["alex", "ben", "charlie", "david", "ethan"];
console.log(arr.length); // 5
const arr = ["alex", "ben", "charlie", "david", "ethan"];
console.log(arr.indexOf("charlie")); // 2
console.log(arr.indexOf("hello world")); // -1 (not found)
Returns the index of the first element that satisfies the condition
.findIndex() is essentially .indexOf() but with a search condition instead of a search value
const arr = [5, 12, 8, 130, 44];
console.log(arr.findIndex(element => element > 20)); // 3
Returns the value of the first element that satisfies the condition. Otherwise undefined is returned.
const arr = ["blue", "red", "green", "purple", "pink", "yellow"];
console.log(arr.find(color => color.length > 5)); // purple
const arr = ["blue", "red", "green", "purple", "pink", "yellow"];
console.log(arr.includes("red")); // true
console.log(arr.includes("rainbow")); // false
// alternative using .indexOf()
console.log(arr.indexOf("red") !== -1); // true
console.log(arr.indexOf("rainbow") !== -1); // false
Returns true if all elements in the array pass the condition
const numbers = [1, 2, 3, 4, 5];
const allGreaterThanZero = numbers.every(i => i > 0);
console.log(allGreaterThanZero); // true
// breaks out of the function once a false value has been found
const arr = [1, 2, 3, "hello", 4, 5];
const allNumbers = arr.every(i => {
console.log(i);
return typeof i === "number";
});
// 1
// 2
// 3
// hello
console.log(allNumbers); // false
Returns true if at least one element in the array passes the condition
// breaks out of the function once a true value has been found
const names = ["alex", "ben", "charlie", "david", "ethan"];
const anyLongerThanFive = names.some(i => {
console.log(i);
return i.length > 5;
});
// alex
// ben
// charlie
console.log(anyLongerThanFive); // true
// .sort() modifies the original array
// if no compare function is provided, it uses localeCompare by default
const months = ["March", "January", "February", "December"];
months.sort();
console.log(months); // ['December', 'February', 'January', 'March'];
// sort by ascending length of string
const months = ["January", "February", "March", "April", "May", "December"];
months.sort((a, b) => a.length - b.length);
console.log(months); // ['May', 'March', 'April', 'January', 'February', 'December']
const numbers = [1, 30, 4, 21, 101];
numbers.sort();
console.log(numbers); // [1, 101, 21, 30, 4]
// sort by ascending order
const numbers = [1, 30, 4, 21, 101];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 4, 21, 30, 101]
// sort by descending order
const numbers = [1, 30, 4, 21, 101];
numbers.sort((a, b) => b - a);
console.log(numbers); // [101, 30, 21, 4, 1]
// .reverse() modifies the original array
const arr = ["one", "two", "three", "four", "five"];
arr.reverse();
console.log(arr); // ['five', 'four', 'three', 'two', 'one']
const zeros = new Array(10).fill(0); // => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Adds one or more elements to the END of the array, it returns the new length of the array
const arr = ["alex", "ben", "charlie", "david", "ethan"];
const arrLength = arr.push("felix", "gerald");
console.log(arr); // ['alex', 'ben', 'charlie', 'david', 'ethan', 'felix', 'gerald']
console.log(arrLength); // 7
Adds one or more elements to the START of an array, it returns the new length of the array
const arr = ["alex", "ben", "charlie", "david", "ethan"];
const arrLength = arr.unshift("adam", "alan");
console.log(arr); // ['adam', 'alan', 'alex', 'ben', 'charlie', 'david', 'ethan']
console.log(arrLength); // 7
Removes the LAST element from an array, it returns the element that was removed
const arr = ["alex", "ben", "charlie", "david", "ethan"];
const popValue = arr.pop();
console.log(arr); // ['alex', 'ben', 'charlie', 'david']
console.log(popValue); // 'ethan'
Removes the FIRST element from an array and returns the element that was removed
const arr = ["alex", "ben", "charlie", "david", "ethan"];
const shiftValue = arr.shift();
console.log(arr); // ['ben', 'charlie', 'david', 'ethan']
console.log(shiftValue); // 'alex'
// .slice() does not modify the original array
const arr = ["alex", "ben", "charlie", "david", "ethan"];
console.log(arr.slice()); // shallow copy of arr
console.log(arr.slice(2)); // ['charlie', 'david', 'ethan']
console.log(arr.slice(2, 3)); // ['charlie']
console.log(arr.slice(2, 4)); // ['charlie', 'david']
console.log(arr.slice(-2)); // ['david', 'ethan']
Returns an array containing the deleted element(s) or an empty array
// .splice() modifies the original array
// insert values into an array
const arr = ["alex", "ben", "charlie", "david", "ethan"];
arr.splice(2, 0, "brandon", "bob");
console.log(arr); // ['alex', 'ben', 'brandon', 'bob', 'charlie', 'david', 'ethan']
// delete values in an array
const arr = ["alex", "ben", "charlie", "david", "ethan"];
arr.splice(2, 1);
console.log(arr); // ['alex', 'ben', 'david', 'ethan']
// get the elements that are removed
const arr = ["alex", "ben", "brandon", "bob", "charlie", "david", "ethan"];
const removedValues = arr.splice(2, 2);
console.log(removedValues); // ['brandon', 'bob']
console.log(arr); // ['alex', 'ben', 'charlie', 'david', 'ethan']
// replace values in an array
const arr = ["alex", "ben", "charlie", "david", "ethan"];
arr.splice(3, 1, "daniel");
console.log(arr); // ['alex', 'ben', 'charlie', 'daniel', 'ethan']
.forEach() executes the callback function once for each array element
const arr = [1, 2, 3, 4, 5];
arr.forEach(i => console.log(`the number is ${i}`));
// the number is 1
// the number is 2
// the number is 3
// the number is 4
// the number is 5
.forEach() with index
const arr = ["a", "b", "c", "d", "e"];
arr.forEach((value, index) => console.log(`index ${index}: ${value}`));
// index 0: a
// index 1: b
// index 2: c
// index 3: d
// index 4: e
.map() creates a new array with the results of the callback function
const arr = [1, 2, 3, 4, 5];
const doubleArr = arr.map(i => i * 2);
console.log(doubleArr); // [2, 4, 6, 8, 10]
.map() with index
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [100, 200, 300, 400, 500];
const sumArray = arr1.map((val, index) => val + arr2[index]);
console.log(sumArray); // [101, 202, 303, 404, 505]
.filter() creates a new array with all elements that pass the test in the callback function
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const moreThanFive = arr.filter(i => i > 5);
console.log(moreThanFive); // [6, 7, 8, 9, 10]
const stuff = ["foo", "bar", "MacBook", "this is a long string"];
const longWords = stuff.filter(i => i.length > 5);
console.log(longWords); // ['MacBook', 'this is a long string']
.reduce() executes a reducer callback function on each member of the array, returns a single output value. The initialValue is optional.
const numbers = [1, 2, 3, 4, 5];
const total = numbers.reduce((total, current) => total + current);
console.log(total); // 15
// with initial value
function addTen(arr) {
return arr.reduce((acc, cur) => acc + cur, 10);
}
const numbers = [1, 3, 5];
console.log(addTen(numbers)); // 19
// example use case for counting occurrence instead of using a for of loop
const numbers = [1, 2, 3, 4, 5, 6, 1, 1, 1];
const count = (array, searchValue) => {
return array.reduce((accumulator, current) => {
// the line below implements the check
const occurrence = current === searchValue ? 1 : 0;
return accumulator + occurrence;
// 0 represents the initial count value
}, 0);
};
console.log(count(numbers, 1)); // 4
// return the largest value in an array without using Math.max
const numbers = [1, 3, 5, 7, 9, 8, 6, 4, 2, 1];
const maxValue = arr => {
return arr.reduce((holder, current) => (holder > current ? holder : current));
// initial value implicitly set as the first element in the array
};
console.log(maxValue(numbers)); // 9
// return the smallest value in an array without using Math.min
const numbers = [1, 3, 5, 7, 9, 8, 6, 4, 2, 1];
const minValue = arr => {
return arr.reduce((holder, current) => (holder < current ? holder : current));
// initial value implicitly set as the first element in the array
};
console.log(minValue(numbers)); // 1
Use for...of to iterate over iterable objects such as strings and arrays
const arr = [1, 2, 3, 4, 5];
let total = 0;
for (let number of arr) {
total += number;
}
console.log(total); // 15
const person = {
name: "David",
age: 30,
occupation: "developer"
};
const { name, age, occupation: job } = person;
console.log(name); // David
console.log(age); // 30
console.log(job); // developer
const { a, b, ...others } = { a: 10, b: 20, c: 30, d: 40, e: 50 };
console.log(a); // 10
console.log(b); // 20
console.log(others); // { c: 30, d: 40, e: 50 }
Easiest way to create an object by using the object literal syntax
const obj = {
key1: "value1",
key2: "value2",
key3: "value3"
};
// getting properties
console.log(obj.key1); // value1
console.log(obj["key2"]); // value2
// adding new properties
// use the square bracket notation for special characters or for an unknown key
obj.key4 = "value4"; // dot notation
obj["special-key"] = "special value"; // square bracket notation
console.log(obj);
/*
{ key1: 'value1',
key2: 'value2',
key3: 'value3',
key4: 'value4',
'special-key': 'special value' }
*/
// removing properties
delete obj.key4;
delete obj["special-key"];
console.log(obj);
// { key1: 'value1', key2: 'value2', key3: 'value3' }
// return keyword has to be used with factory function
// note that there is no need for name: name, gender: gender
// get keyword used to define a getter (access an object's method like a property)
function createPerson(name, gender, yearOfBirth) {
return {
location: "Singapore",
name,
gender,
get age() {
return new Date().getFullYear() - yearOfBirth;
}
};
}
const peter = createPerson("peter", "male", 1995);
console.log(peter.location); // Singapore
console.log(peter.name); // peter
console.log(peter.age); // 23 (AS OF 2018)
// new keyword has to be used with constructor function
// note uppercase first letter (Pascal case) used for constructor function
function Person(name, gender, yearOfBirth) {
this.location = "Singapore";
this.name = name;
this.gender = gender;
this.age = new Date().getFullYear() - yearOfBirth;
}
const alex = new Person("alex", "male", 2000);
console.log(alex.location); // Singapore
console.log(alex.name); // alex
console.log(alex.age); // 18 (AS OF 2018)
Use for...in to iterate over an object
// for...in returns the object's own instance properties/methods and also those from the prototype
const book = {
title: "JavaScript: The Definitive Guide",
author: "David Flanagan",
publisher: "O'Reilly Media"
};
for (let key in book) {
console.log(`${key} is ${book[key]}`);
}
// title is JavaScript: The Definitive Guide
// author is David Flanagan
// publisher is O'Reilly Media
Returns an array of the object's keys
// returns only the object's own instance properties/methods
const person = {
name: "mary",
age: 32
};
console.log(Object.keys(person)); // ['name', 'age']
Returns an array of the object's values
const person = {
name: "mary",
age: 32
};
console.log(Object.values(person)); // ['mary', 32]
Returns an array of the object's own enumerable property [key, value] pairs
const person = {
name: "mary",
age: 32
};
console.log(Object.entries(person)); // [['name', 'mary'], ['age', 32]]
Returns true if the property is in the object or its prototype chain
const person = {
name: "mary",
age: 32
};
if ("name" in person) console.log(`person has a name ${person.name}`);
// person has a name mary
Returns true if the object has the specified property as its own property (not inherited)
function Animal(name, species) {
this.name = name;
this.species = species;
}
Animal.prototype.eat = function() {
console.log("Eating!");
};
const cooper = new Animal("Cooper", "dog");
cooper.bark = function() {
console.log("WOOF WOOF!");
};
cooper.eat(); // Eating!
cooper.bark(); // WOOF WOOF!
console.log(cooper.hasOwnProperty("eat")); // false (inherited from prototype)
console.log(cooper.hasOwnProperty("bark")); // true
With the descriptor, we can modify the way the property behaves
By default, the properties added are immutable and not enumerable
const exampleObject = { hello: "world" };
Object.defineProperty(exampleObject, "exampleKey", {
value: "exampleValue"
});
console.log(exampleObject);
// browser: {hello: 'world', exampleKey: "exampleValue"}
// node: {hello: 'world'}
console.log("exampleKey" in exampleObject); // true
console.log(Object.keys(exampleObject)); // ['hello']
for (let key in exampleObject) console.log(key); // hello
delete exampleObject.hello;
delete exampleObject.exampleKey;
console.log(exampleObject);
// browser: { exampleKey: "exampleValue" }
// node: {}
Create a shallow copy by using an empty object as the target
const object1 = { a: 1, b: 2, c: 3 };
const clone = Object.assign({}, object1);
console.log(clone); // { a: 1, b: 2, c: 3 }
console.log(object1 === clone); // false (object1 and clone are 2 different objects)
Use Object.assign() to merge objects
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };
const newObj = Object.assign(obj1, obj2, obj3);
console.log(newObj); // { a: 1, b: 2, c: 3 }
console.log(obj1); // { a: 1, b: 2, c: 3 }
console.log(newObj === obj1); // true
Alternative using the spread operator (reassign a new object)
let obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };
const newObj = { ...obj1, ...obj2, ...obj3 };
obj1 = newObj;
console.log(newObj); // { a: 1, b: 2, c: 3 }
In most cases, the value of "this" is determined by how a function is called.
If strict mode is enabled, "this" that returns window in browser/global in node will instead return undefined
ES6 arrow functions do not rebind the "this" keyword
const person = {
name: "george",
getThis() {
return this;
},
getDeepThis() {
function example() {
return this;
}
return example();
},
arrowDeepThis() {
const arrowFunc = () => {
return this;
};
return arrowFunc();
}
};
console.log(person.getThis()); // person object
console.log(person.getDeepThis()); // window in browser, global in node
console.log(person.arrowDeepThis()); // person object
These 3 methods all involve the use of the "this" keyword
.bind(thisArg)
const person = {
name: "george",
getThis() {
return this;
},
getDeepThis() {
function example() {
return this;
}
return example.bind(this)();
}
};
console.log(person.getDeepThis()); // person object
.call(thisArg, ...arguments)
function printer(greeting) {
console.log(`${greeting}, this is ${this.name}`);
}
const object1 = {
name: "object1"
};
const object2 = {
name: "object2"
};
printer.call(object2, "Hi there"); // Hi there, this is object2
.apply(thisArg, [arguments array])
function printer(...numbers) {
console.log(`In ${this.name}, we have ${numbers}`);
}
const object1 = {
name: "object1"
};
printer.apply(object1, [100, 99, 98, 97, 96, 95]); // In object1, we have 100,99,98,97,96,95
ES6 Classes are syntactic sugar over constructor functions
class Person {
constructor(name, gender, yearOfBirth) {
this.name = name;
this.gender = gender;
this.age = new Date().getFullYear() - yearOfBirth;
}
}
// all objects inherit properties and methods from a prototype, you can think of prototypes as the parent
function Person(name, gender, yearOfBirth) {
this.location = "Singapore";
this.name = name;
this.gender = gender;
this.age = new Date().getFullYear() - yearOfBirth;
}
const jack = new Person("jack", "male", 1980);
console.log(Object.getPrototypeOf(jack)); // returns the prototype of Person
console.log(jack.constructor); // returns the Person function
// modifying the example above, adding methods to the Person prototype
function Person(name, gender, yearOfBirth) {
this.name = name;
this.gender = gender;
this.yearOfBirth = yearOfBirth;
}
Person.prototype.getAge = function() {
return new Date().getFullYear() - this.yearOfBirth;
};
Person.prototype.walk = function() {
console.log(`${this.name} is walking...`);
};
const sam = new Person("sam", "female", 1998);
sam.walk(); // sam is walking...
console.log(sam.getAge()); // 20 (AS OF 2018)
// comparing the prototypes of objects, continuing from the example above
const sam = new Person("sam", "female", 1998);
const daniel = new Person("daniel", "male", 1950);
console.log(Object.getPrototypeOf(daniel) === Object.getPrototypeOf(sam)); // true
console.log(Object.getPrototypeOf(sam) === Person.prototype); // true
console.log(sam.__proto__ === Person.prototype); // true
Object.create() creates a new object, setting the argument object as the new object's __proto__
// this is an object, not a constructor function
const person = {
isHuman: true,
greeting: function() {
console.log(
`My name is ${this.name}. Am I human? ${this.isHuman ? "Yes" : "No"}`
);
}
};
const james = Object.create(person);
james.name = "James";
james.greeting(); // My name is James. Am I human? Yes
james.__proto__ === person; // true
Declaration: They are hoisted to the top of the file, you CAN use them before they are declared.
Expression: They are not hoisted, you CANNOT use them before they are expressed.
Note: The easiest way to distinguish declaration vs. expression is the position of the word "function" in the statement (not just a line, but a distinct statement). If "function" is the very first thing in the statement, then it's a function declaration. Otherwise, it's a function expression. - "You don't know JS" by Kyle Simpson
// Declaration
function helloDeclaration() {
console.log("hello declaration");
}
// Expression
const helloExpression = function() {
console.log("hello expression");
};
// OKAY
logPlus2(10); // 10 + 2 = 12
function logPlus2(num) {
console.log(`${num} + 2 = ${num + 2}`);
}
// NOT OKAY
logMinus2(5); // logMinus2 is not defined
const logMinus2 = function(num) {
console.log(`${num} - 2 = ${num - 2}`);
};
// use "()" for no arguments
const arrowFunction = () => console.log("WOOHOO ARROW FUNCTION");
// no need for "()" for a single argument
// no need for "{}" and return keyword for single line functions
const add2 = number => number + 2;
// use () for functions with more than 1 argument
// use {} and return for multiline functions
const rectangle = (length, breadth) => {
const area = length * breadth;
const perimeter = 2 * length + 2 * breadth;
return {
area,
perimeter
};
};
Higher order functions are functions that either return a function or take function(s) as arguments.
Note: Array methods such as forEach, map, reduce, filter are all higher order functions.
Example: "Calculating with Functions" from Codewars
const numberMaker = (n, func) => (func === undefined ? n : func(n));
const zero = func => numberMaker(0, func);
const one = func => numberMaker(1, func);
const two = func => numberMaker(2, func);
const three = func => numberMaker(3, func);
const four = func => numberMaker(4, func);
const five = func => numberMaker(5, func);
const six = func => numberMaker(6, func);
const seven = func => numberMaker(7, func);
const eight = func => numberMaker(8, func);
const nine = func => numberMaker(9, func);
const plus = ins => outs => outs + ins;
const minus = ins => outs => outs - ins;
const times = ins => outs => outs * ins;
const dividedBy = ins => outs => outs / ins;
two(times(three())); // => 6
nine(dividedBy(three())); // => 3
one(plus(four())); // => 5
A generator function can be paused and resumed later. It uses the "yield" and "next" keywords.
// yield will "return" the value and pause the generator
function* plusOne(startValue) {
while (true) {
yield (startValue += 1);
}
}
// calling next will resume the generator where it left off
// resumes in the while (true) loop and next() can be called as many times
const moreThan10 = plusOne(10);
moreThan10.next(); // => { value: 11, done: false }
moreThan10.next(); // => { value: 12, done: false }
moreThan10.next().value; // => 13
moreThan10.next().value; // => 14
const favNumbers = function*() {
yield 7;
yield 13;
yield 17;
yield 19;
};
const showNumbers = favNumbers();
showNumbers.next(); // => { value: 7, done: false }
showNumbers.next(); // => { value: 13, done: false }
showNumbers.next(); // => { value: 17, done: false }
showNumbers.next(); // => { value: 19, done: false }
showNumbers.next(); // => { value: undefined, done: true }
const samplePerson = '{"name":"david", "age":42}';
console.log(typeof samplePerson); // string
console.log(samplePerson.name); // undefined
const parsedPerson = JSON.parse(samplePerson);
console.log(typeof parsedPerson); // object
console.log(parsedPerson); // {name: 'david', age: 42}
console.log(parsedPerson.name); // david
const milkStr = '["full-cream", "low-fat", "skim", "soy", "almond"]';
console.log(typeof milkStr); // string
console.log(milkStr.length); // 50 (characters in the string)
const milks = JSON.parse(milkStr);
console.log(Array.isArray(milks)); // true
console.log(milks); // ['full-cream', 'low-fat', 'skim', 'soy', 'almond']
console.log(milks.length); // 5 (elements in the array)
const myStuff = {
laptop: "MacBook Pro",
watch: "Casio F-91W",
bottle: "Dasani"
};
console.log(typeof myStuff); // object
console.log(myStuff.laptop); // MacBook Pro
const stringStuff = JSON.stringify(myStuff);
console.log(typeof stringStuff); // string
console.log(stringStuff); // '{"laptop":"MacBook Pro","watch":"CasioF-91W","bottle":"Dasani"}'
console.log(stringStuff.laptop); // undefined
const pets = ["dog", "cat", "fish", "hamster", "bird", "frog", "horse"];
console.log(Array.isArray(pets)); // true
const strPets = JSON.stringify(pets);
console.log(typeof strPets); // string
console.log(strPets); // '["dog","cat","fish","hamster","bird","frog","horse"]'
shallow copy with spread operator
const numsInNums = [1, 2, 3, [4, 5, [6, 7]]];
const newNums = [...numsInNums];
console.log(numsInNums === newNums); // false
newNums[0] = "ONE";
newNums[3][0] = "FOUR";
console.log(newNums); // ['ONE', 2, 3, ['FOUR', 5, [6, 7]]];
console.log(numsInNums); // [1, 2, 3, ['FOUR', 5, [6, 7]]];
simple deep clone with JSON.parse(JSON.stringify(array/object))
const numsInNums = [1, 2, 3, [4, 5, [6, 7]]];
const newNums = JSON.parse(JSON.stringify(numsInNums));
console.log(numsInNums === newNums); // false
newNums[0] = "ONE";
newNums[3][0] = "FOUR";
console.log(newNums); // ['ONE', 2, 3, ['FOUR', 5, [6, 7]]];
console.log(numsInNums); // [1, 2, 3, [4, 5, [6, 7]]]
const thisTakesTime = () => {
console.log("waiting, waiting, waiting");
setTimeout(() => console.log("okay done!"), 3000);
};
thisTakesTime();
// waiting, waiting, waiting
// * 3 seconds delay *
// okay done!
const countdownTimer = seconds => {
console.log(seconds);
const timer = setInterval(() => {
if (seconds <= 0) {
console.log("DONE!");
clearInterval(timer);
}
console.log(seconds);
seconds -= 1;
}, 1000);
};
countdownTimer(5);
// 5
// 4
// 3
// 2
// 1
// DONE!
// 0
The states of a promise:
pending: initial state, neither fulfilled nor rejected.
resolved/fulfilled: the operation completed successfully.
rejected: the operation failed.
const p = new Promise((resolve, reject) => {
// perform async operation here
setTimeout(() => {
resolve("Success!"); // pending => resolved/fulfilled
reject(new Error("Error!")); // pending => rejected
}, 2000);
});
p.then(result => console.log(result)).catch(err =>
console.log(`Error: ${err.message}`)
);
// Success! (after 2 seconds)
function databaseQuery2Seconds() {
return new Promise(resolve => {
setTimeout(() => {
console.log("Received result from database");
resolve({ name: "Mark", age: 32 });
}, 2000);
});
}
async function getUserData() {
console.log("Searching database for user");
const result = await databaseQuery2Seconds();
console.log(result);
}
getUserData();
// Searching database for user
// * 2 seconds delay *
// Received result from database
// { name: 'Mark', age: 32 }
async function getPosts() {
const response = await fetch("https://jsonplaceholder.typicode.com/posts");
const json = await response.json();
return json;
}
const wrapper = async () => {
const posts = await getPosts();
console.log(posts);
};
// some posts in JSON here...
Creating an instance of the Error object
throw new Error("this is an error");
// In Chrome
//Uncaught Error: this is an error
// In Node
// Error: this is an error
function includes2(input) {
return input.indexOf("2") !== -1;
}
const num = 12345;
try {
includes2(num);
} catch (err) {
console.log(err.name);
console.log(err.message);
}
// TypeError
// input.indexOf is not a function
finally will execute regardless of the try...catch block
try {
console.log("hello world!");
} catch (err) {
console.log("Error:", err.message);
} finally {
console.log("finally this runs");
}
// hello world!
// finally this runs
try {
throw new Error("this is an error");
} catch (err) {
console.log("Error:", err.message);
} finally {
console.log("finally this runs");
}
// Error: this is an error
// finally this runs
Finally will execute regardless of any return statements in the try...catch block
function errorExample() {
try {
throw new Error("oh no, an error occurred");
return "try, all is good";
} catch (err) {
console.log(err.message);
return "catch, something went wrong";
} finally {
console.log("looks like we are done");
return "finally, this has to execute before the rest of try..catch";
}
}
console.log(errorExample());
// oh no, an error occurred
// looks like we are done
// finally, this has to execute before the rest of try..catch
const alphabets = "abcdefg";
const reverser = input =>
input
.split("")
.reverse()
.join("");
console.log(reverser(alphabets)); // gfedcba
const str = "foobar";
const caps = input => input[0].toUpperCase() + input.slice(1);
console.log(caps(str)); // Foobar
// Capitalise first letter of every word
const sentence = "this is a sentence";
const up = input =>
input
.split(" ")
.map(word => word[0].toUpperCase() + word.slice(1))
.join(" ");
console.log(up(sentence)); // This Is A Sentence
const arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 0];
const removeDuplicates = input => {
const res = [];
for (let i = 0; i < input.length; i++) {
// Single line if statement for only true value
if (res.indexOf(input[i]) == -1) res.push(arr[i]);
}
return res;
};
console.log(removeDuplicates(arr)); // [1,2,3,4,5,6,7,8,9,0]
The Set object lets you store unique values of any type, whether primitive values or object references.
const removeDuplicatesSet = input => [...new Set(input)];
console.log(removeDuplicatesSet(arr)); // [1,2,3,4,5,6,7,8,9,0]
arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 7, 8, 9, 0];
const findUnique = input => {
return input.filter(i => input.indexOf(i) == input.lastIndexOf(i));
};
console.log(findUnique(arr)); // [6,7,8,9,0]