Leveraging ES6 Destructuring and Core Features for Modern JavaScript
Array Destructuring
Traditional syntax for extracting array values involves verbose index referencing.
let numberList = [1, 2, 3];
let x = numberList[0];
let y = numberList[1];
let z = numberList[2];
console.log(x, y, z);
ES6 destructuring provides a concise alternative.
let numberList = [1, 2, 3];
let [x, y, z] = numberList;
console.log(x, y, z);
Object Destructuring
Similar destructuring applies to objects, alowing for direct property extraction.
const user = {
username: "alex",
userAge: 30,
knownTech: ['python', 'js', 'html']
}
// Destructure the object
const { username, userAge, knownTech } = user;
console.log(username, userAge, knownTech);
Properties can be assigned to different variable names during destructuring.
const { username: id, userAge, knownTech } = user;
console.log(id, userAge, knownTech); // Variable 'id' holds the value from 'username'
String Enhancements
New string methods simplify common checks.
let greeting = "hello.world";
console.log(greeting.startsWith("hello")); // true
console.log(greeting.endsWith(".world")); // true
console.log(greeting.includes("o")); // true
console.log(greeting.includes("world")); // true
Template literals (backticks ``) enable multi-line strings and easy interpolation of variables and expressions.
let markup = `<section>
<p>Sample text</p>
</section>`;
console.log(markup);
function getMessage() {
return "a greeting";
}
let userInfo = `I am ${id}, ${userAge + 5} years next year, note: ${getMessage()}`;
console.log(userInfo);
Function Improvements
Default parameters provide a cleaner syntax for optional arguments.
function calculateSum(firstVal, secondVal = 5) {
return firstVal + secondVal;
}
console.log(calculateSum(25)); // 30
Rest parameters (...) collect multiple arguments in to an array.
function countArgs(...args) {
console.log(args.length);
}
countArgs(10, 20); // 2
countArgs(10, 20, 30, 40); // 4
Arrow functions offer a compact syntax and lexical scoping of this.
let logValue = input => console.log(input);
logValue("test");
let addValues = (val1, val2) => val1 + val2;
console.log(addValues(5, 15)); // 20
let addValuesComplex = (val1, val2) => {
let interim = val1 + val2;
return val1 + interim;
}
console.log(addValuesComplex(5, 10)); // 20
Arrow functions can be combined with destructuring in parameters.
const user = { username: "alex", userAge: 30 };
let greetUser = ({username}) => console.log("Hello, " + username);
greetUser(user);
Object Enhancements
New static methods on Object are useful for introspection.
console.log(Object.keys(user)); // ["username", "userAge", "knownTech"]
console.log(Object.values(user)); // ["alex", 30, Array(3)]
console.log(Object.entries(user)); // [Array(2), Array(2), Array(2)]
Object.assign merges properties from source objects into a target.
const destination = { propA: 10 };
const originOne = { propB: 20 };
const originTwo = { propC: 30 };
Object.assign(destination, originOne, originTwo);
console.log(destination); // { propA: 10, propB: 20, propC: 30 }
Object literal shorthand simplifies initialization when property names match variable names.
const height = 180;
const firstName = "Lee";
const personShort = { height, firstName }; // Equivalent to { height: height, firstName: firstName }
console.log(personShort);
Methods within objects can be defined with a concise syntax.
let animal = {
species: "cat",
// Traditional
makeSoundOld: function() { console.log("Meow"); },
// Arrow function (caution with `this`)
makeSoundArrow: () => console.log(animal.species + " meows"),
// Concise method syntax
makeSoundNew() { console.log(this.species + " meows loudly"); }
};
animal.makeSoundNew();
The spread operator (...) facilitates object copying and merging.
// Shallow copy
let original = { title: "Book", pages: 300 };
let copy = { ...original };
console.log(copy);
// Merge objects
let infoA = { id: 100 };
let infoB = { status: "active" };
let merged = { ...infoA, ...infoB };
console.log(merged); // { id: 100, status: "active" }
Array Methods: Map and Reduce
map() transforms each element in an array, returning a new array.
let strNumbers = ['4', '40', '-10', '6'];
let numNumbers = strNumbers.map(element => element * 2);
console.log(numNumbers); // [8, 80, -20, 12]
reduce() condenses an array to a single value by applying a callback function cumulatively.
let total = numNumbers.reduce((accumulator, currentValue) => {
console.log(`Accumulated: ${accumulator}, Current: ${currentValue}`);
return accumulator + currentValue;
}, 200); // 200 is the initial value for accumulator
console.log(`Final total: ${total}`);
Managing Asynchronous Operations with Promises
Promises encapsulate asynchronous tasks, improving callback management and error handling.
function fetchResource(url) {
return new Promise((fulfill, reject) => {
// Simulating an AJAX call
setTimeout(() => {
let mockData = { id: 123, name: "Data from " + url };
fulfill(mockData);
// reject("Error simulated"); // Uncomment to test error path
}, 100);
});
}
fetchResource("/api/data")
.then(response => {
console.log("Step 1 success:", response);
return fetchResource(`/api/details/${response.id}`);
})
.then(detailedResponse => {
console.log("Step 2 success:", detailedResponse);
return fetchResource(`/api/scores/${detailedResponse.id}`);
})
.then(finalResponse => {
console.log("Step 3 success:", finalResponse);
})
.catch(error => {
console.error("An error occurred:", error);
});
Module System
The ES6 module system uses export to expose functionality from a file and import to use it in another.
export can be applied to any JavaScript variable: primitives, functions, arrays, or objects.
Example export (utils.js):
export const apiKey = 'ABC123';
export function formatDate(date) { /* ... */ }
export default class Helper { /* ... */ }
Example import (app.js):
import Helper, { apiKey, formatDate } from './utils.js';