Syntax
let
and const
- Variables declared with
let
andconst
are scoped to the block, not to the function. - Variables declared with
let
andconst
can only be accessed after they have been declared. - They eliminate issues from hoisting.
- Variables declared with
let
can be reassigned, but can’t be redeclared in the same scope. - Variables declared with
const
must be assigned an initial value, but can’t be redeclared, or reassigned in the same scope.
Template literals
- The old way to concatenate strings is by using the string concatenation operator (
+
). - Template literals are string literals that include embedded expressions.
- Template literals in JavaScript are denoted with backticks (`), and can template literals can contain placeholders which are represented using
${expression}
. - Template literals preserve newlines as part of the string.
Destructuring
- Data can be extracted from arrays and objects into distinct variables using destructuring.
- From array
const point = [10, 25, -34, 15, 9];
// destructuring
const [x, y, z] = point;
// x: 10
// y: 25
// z: -34
// ignore y
const [ x, , z ] = point;
// x: 10
// z: -34
- From object
const gemstone = {
type: 'quartz',
color: 'rose',
carat: 21.29
};
const { type, carat } = gemstone;
// type: quartz
// carat: 21.29
Object literal shorthand
- If the properties have the same name as the variables being assigned to them in an object literal, variable names can be removed.
let type = 'quartz';
let color = 'rose';
let carat = 21.29;
const gemstone = {
type: type,
color: color,
carat: carat,
calculateWorth: function() {
// ...
}
};
// it is equivalent to
const gemstone = {
type,
color,
carat,
// shorthand method name
calculateWorth() {
// ...
}
};
Iteration
- Iterable protocol
- Allow JavaScript objects to define or customize their iteration behavior.
for...of
loop- A loop that iterates over iterable objects.
Family of for
loops
for
loop- Need to keep track of the counter and exit condition.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0; i < digits.length; i++) {
console.log(digits[i]);
}
for...in
loop- Iterate with index.
- Loop over all enumerable properties, including any additional properties of the array's prototype.
Array.prototype.decimalfy = function() {
for (let i = 0; i < this.length; i++) {
this[i] = this[i].toFixed(2);
}
};
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0; i < digits.length; i++) {
console.log(digits[i]);
}
// the decimalfy function will be printed out at the end
for...of
loop- Loop over any type of data that is iterable.
- Only loop over the values in the object.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
console.log(digit);
}
// custom function won't be included
The iterable
protocol
- The
iterable
protocol is used for defining and customizing the iteration behavior of objects. - Any object that is iterable can use the new
for...of
loop. - For an object to be iterable, it must implement the
iterable
interface.- The iterator method is available via the constant
[Symbol.iterator]
. - The iterator method is a zero argument function that returns an iterator object.
- An iterator object is an object that conforms to the iterator protocol.
- The iterator method is available via the constant
the iterator
protocol
- The
iterator
protocol is used to define a standard way that an object produces a sequence of values. - This is done through implementing the
next()
method, a zero argument function that returns an object with two properties.value
: the data representing the next value in the sequence of values within the object.done
: a boolean representing if the iterator is done going through the sequence of values.- If
done
istrue
, then the iterator has reached the end of its sequence of values. - If
done
isfalse
, then the iterator is able to produce another value in its sequence of values.
- If
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const arrayIterator = digits[Symbol.iterator]();
console.log(arrayIterator.next());
// Object {value: 0, done: false}
console.log(arrayIterator.next());
// Object {value: 1, done: false}
console.log(arrayIterator.next());
// Object {value: 2, done: false}
Spread operator
- The spread operator (
...
) expands, or spreads, iterable objects into multiple elements.
const primes = new Set([2, 3, 5, 7]);
console.log(...primes);
// 2 3 5 7
- This operator is useful for combining arrays.
const fruits = ["apples", "bananas", "pears"];
const vegetables = ["corn", "potatoes", "carrots"];
const produce = [...fruits, ...vegetables];
Rest parameter
- The rest parameter (
...
) can represent an indefinite number of elements as an array.
const order = [20.17, 18.67, "cheese", "eggs"];
const [total, subtotal, ...items] = order;
// total: 20.17
// subtotal: 18.67
// items: ["cheese", "eggs"]
- Useful for defining variadic functions
- Variadic functions are functions that take an indefinite number of arguments.
// define variadic function with arguments object
function sum() {
let total = 0;
for(const argument of arguments) {
total += argument;
}
return total;
}
// define variadic function with rest parameter
function sum(...nums) {
let total = 0;
for(const num of nums) {
total += num;
}
return total;
}