An array is a special variable, which can hold more than one value at a time.
Three ways to iterate an Array:
-
Sequential for loop:
var myStringArray = ["Hello","World"]; var arrayLength = myStringArray.length; for (var i = 0; i < arrayLength; i++) { console.log(myStringArray[i]); //Do something }
Pros
- Works on every environment
- You can use break and continue flow control statements
Cons
- Too verbose
- Imperative
- Easy to have off-by-one errors (sometimes also called a fence post error)
-
Array.prototype.forEach
const array = ["one", "two", "three"] array.forEach(function (item, index) { console.log(item, index); });
And with the ES6 arrow function syntax, it's even more succinct:
array.forEach(item => console.log(item));
Pros
- Very short and succinct.
- Declarative
Cons
- Cannot use break / continue
-
ES6 for-of statement
let colors = ['red', 'green', 'blue']; for (const color of colors){ console.log(color); }
Pros
- It can iterate over a large variety of objects.
- Can use normal flow control statements (break / continue).
- Useful to iterate serially asynchronous values.
Cons
- If you are targeting older browsers, the transpiled output might surprise you.
-
Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present']; const result = words.filter(word => word.length > 6); console.log(result); // expected output: Array ["exuberant", "destruction", "present"]
-
Array.prototype.find()
The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
const array1 = [5, 12, 8, 130, 44]; const found = array1.find(element => element > 10); console.log(found); // expected output: 12
-
Array.prototype.findIndex()
The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise, it returns -1, indicating that no element passed the test.
const array1 = [5, 12, 8, 130, 44]; const isLargeNumber = (element) => element > 13; console.log(array1.findIndex(isLargeNumber)); // expected output: 3
-
Array.prototype.forEach()
The forEach() method executes a provided function once for each array element.
const array1 = ['a', 'b', 'c']; array1.forEach(element => console.log(element)); // expected output: "a" // expected output: "b" // expected output: "c"
-
Array.prototype.includes()
The includes() method determines whether an array includes a certain value among its entries, returning true or false as appropriate.
const array1 = [1, 2, 3]; console.log(array1.includes(2)); // expected output: true const pets = ['cat', 'dog', 'bat']; console.log(pets.includes('cat')); // expected output: true console.log(pets.includes('at')); // expected output: false
-
Array.prototype.indexOf()
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
const beasts = ['ant', 'bison', 'camel', 'duck', 'bison']; console.log(beasts.indexOf('bison')); // expected output: 1 // start from index 2 console.log(beasts.indexOf('bison', 2)); // expected output: 4 console.log(beasts.indexOf('giraffe')); // expected output: -1
-
Array.prototype.join()
The join() method creates and returns a new string by concatenating all of the elements in an array (or an array-like object), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator.
const elements = ['Fire', 'Air', 'Water']; console.log(elements.join()); // expected output: "Fire,Air,Water" console.log(elements.join('')); // expected output: "FireAirWater" console.log(elements.join('-')); // expected output: "Fire-Air-Water"
-
Array.prototype.map()
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
const array1 = [1, 4, 9, 16]; // pass a function to map const map1 = array1.map(x => x * 2); console.log(map1); // expected output: Array [2, 8, 18, 32]
-
Array.prototype.pop()
The pop() method removes the last element from an array and returns that element. This method changes the length of the array.
const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato']; console.log(plants.pop()); // expected output: "tomato" console.log(plants); // expected output: Array ["broccoli", "cauliflower", "cabbage", "kale"] plants.pop(); console.log(plants); // expected output: Array ["broccoli", "cauliflower", "cabbage"]
-
Array.prototype.shift()
The shift() method removes the first element from an array and returns that removed element. This method changes the length of the array.
const array1 = [1, 2, 3]; const firstElement = array1.shift(); console.log(array1); // expected output: Array [2, 3] console.log(firstElement); // expected output: 1
-
Array.prototype.push()
The push() method adds one or more elements to the end of an array and returns the new length of the array.
const animals = ['pigs', 'goats', 'sheep']; const count = animals.push('cows'); console.log(count); // expected output: 4 console.log(animals); // expected output: Array ["pigs", "goats", "sheep", "cows"] animals.push('chickens', 'cats', 'dogs'); console.log(animals); // expected output: Array ["pigs", "goats", "sheep", "cows", "chickens", "cats", "dogs"]
-
Array.prototype.unshift()
The unshift() method adds one or more elements to the beginning of an array and returns the new length of the array.
const array1 = [1, 2, 3]; console.log(array1.unshift(4, 5)); // expected output: 5 console.log(array1); // expected output: Array [4, 5, 1, 2, 3]
-
Array.prototype.reduce()
The reduce() method executes a user-supplied "reducer" callback function on each element of the array, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.
Perhaps the easiest-to-understand case for reduce() is to return the sum of all the elements in an array.
The reducer walks through the array element-by-element, at each step adding the current array value to the result from the previous step (this result is the running sum of all the previous steps) — until there are no more elements to add.
const array1 = [1, 2, 3, 4]; const reducer = (previousValue, currentValue) => previousValue + currentValue; // 1 + 2 + 3 + 4 console.log(array1.reduce(reducer)); // expected output: 10 // 5 + 1 + 2 + 3 + 4 console.log(array1.reduce(reducer, 5)); // expected output: 15
-
Array.prototype.slice()
The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included) where start and end represent the index of items in that array. The original array will not be modified.
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant']; console.log(animals.slice(2)); // expected output: Array ["camel", "duck", "elephant"] console.log(animals.slice(2, 4)); // expected output: Array ["camel", "duck"] console.log(animals.slice(1, 5)); // expected output: Array ["bison", "camel", "duck", "elephant"] console.log(animals.slice(-2)); // expected output: Array ["duck", "elephant"] console.log(animals.slice(2, -1)); // expected output: Array ["camel", "duck"]
- A JavaScript Set is a collection of unique values.
- Each value can only occur once in a Set.
- A set can be created either by passing an array to new set() or using add() function
const letters = new Set(['a','b','c']);
letters.add('d');
letters.delete('b');
Method | Description |
---|---|
new Set() | Creates a new Set |
add() | Adds a new element to the Set |
delete() | Removes an element from a Set |
has() | Returns true if a value exists in the Set |
forEach() | Invokes a callback for each element in the Set |
values() | Returns an iterator with all the values in a Set |
Property | Description |
size | Returns the number elements in a Set |
The WeakSet object lets you store weakly held objects in a collection.
The main differences to the Set object are:
- WeakSets are collections of objects only. They cannot contain arbitrary values of any type, as Sets can.
- The WeakSet is weak, meaning references to objects in a WeakSet are held weakly. If no other references to an object stored in the WeakSet exist, those objects can be garbage collected.
- A Map holds key-value pairs where the keys can be any datatype.
- A Map remembers the original insertion order of the keys.
- You can create a map by Passing an Array to new Map() or by using Map.set()
const fruits = new Map([
["apples", 500],
["bananas", 300],
["oranges", 200]
]);
fruits.set("mango", 500);
Method | Description |
---|---|
new Map() | Creates a new Map |
set() | Sets the value for a key in a Map |
get() | Gets the value for a key in a Map |
delete() | Removes a Map element specified by the key |
has() | Returns true if a key exists in a Map |
forEach() | Calls a function for each key/value pair in a Map |
entries() | Returns an iterator with the [key, value] pairs in a Map |
Property | Description |
size | Returns the number of elements in Map |
The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced. The keys must be objects and the values can be arbitrary values.
- Arrow functions were introduced in ES6.
- Arrow functions allows a short syntax for writing function expressions.
- You don't need the function keyword, the return keyword, and the curly brackets.
// ES5
var x = function(x, y) {
return x * y;
}
// ES6
const x = (x, y) => x * y;
- Generators are a special class of functions that simplify the task of writing iterators.
- A generator is a function that produces a sequence of results instead of a single value, i.e you generate a series of values.
function *infiniteSequence() { // Creates a generator function
let n = 1;
while(true) {
yield n++;
}
}
const numbers = infiniteSequence();
numbers.next(); // {value: 1, done: false}
numbers.next(); // {value: 2, done: false}
numbers.next(); // {value: 3, done: false}
Yield an operator with which a generator can pause itself. Every time a generator encounters a yield, it "returns" the value specified after it.
Once all the values have been yielded, the done becomes true or by using return instead of yield, it becomes true. Below is an example where the yield becomes true
function *myFunction() {
yield 'Hello';
yield 'Hi';
}
const myFunc = myFunction();
myFunc.next(); // {value: 'Hi', done: false}
myFunc.next(); // {value: 'Hi', done: false}
myFunc.next(); // {value: undefined, done: true}
The call() method is a predefined JavaScript method.
It can be used to invoke (call) a method with an owner object as an argument (parameter).
const person = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
const person1 = {
firstName:"John",
lastName: "Doe"
}
const person2 = {
firstName:"Mary",
lastName: "Doe"
}
// This will return "Mary Doe"
person.fullName.call(person2);
The call method can accept arguments as well
const person = {
fullName: function(city, country) {
return this.firstName + " " + this.lastName + ", " + city + ", " + country;
}
}
const person1 = {
firstName:"John",
lastName: "Doe"
}
person.fullName.call(person1, "Oslo", "Norway"); // John Doe, Oslo, Norway
Hoisting is JavaScript's default behavior of moving all declarations to the top of the current scope (to the top of the current script or the current function).
var x; // Declare x
x = 5; // Assign 5 to x
elem = document.getElementById("demo"); // Find an element
elem.innerHTML = x; // Display x in the element
Hoisting only works for declarations, not initializations. So,
console.log(y); // Undefined
var y = 13;
The above code will give undefined as output, as it is the same as writing,
var y;
console.log(y);
y = 13;
Observe how the declaration var y is hoisted, but y = 13 is not, as only the declarations are hoisted!
Hoisting does not occur with let or const, using them will increase the chances of your code being bug free (a lot).
Use JavaScript strict mode, using the use strict
directive at top; JavaScript strict mode does not allow undeclared variables.
Global variables can be made local (private) with closures.
const add = (function () { // Notice that the function itself is enclosed within the brackets
let counter = 0; // This initialization happens only once, when the file is loaded
return function () {
counter += 1;
return counter
}
})();
add(); // the counter is now 1
add(); // the counter is now 2
add(); // the counter is now 3
// Below is a normal function. notice the difference on how it is initialized
const normalFunction = function() {
let counter = 0;
return function() {
counter ++;
return counter;
}
}
A callback is a function passed as an argument to another function.
function myDisplayer(some) {
document.getElementById("demo").innerHTML = some;
}
function myCalculator(num1, num2, myCallback) {
let sum = num1 + num2;
myCallback(sum); // This invokes the callback to myDisplayer function
}
myCalculator(5, 5, myDisplayer); // When you pass a function as an argument, remember not to use parenthesis.