Learn JavaScript ES6+ features in this Day 6 tutorial. Dive into arrow functions, destructuring, template literals, and modules with hands-on examples.
ES6 (ECMAScript 2015) is the release that changed how everyday JavaScript reads. If you learned the language before it, your old habits still work, but the new syntax says the same thing with less noise. Today, Day 6, covers the pieces you’ll reach for most: arrow functions, template literals, destructuring, the spread and rest operators, and modules. None of it is magic, just clearer ways to do what you already do.
Table of Contents
- Arrow Functions
- Template Literals
- Destructuring
- Spread Operator
- Rest Operator
- Modules
- Import/Export
- Conclusion
Arrow Functions
Arrow functions give you a shorter way to write function expressions. The bigger difference is this: an arrow function doesn’t get its own this, it borrows the one from the scope around it. That fixes a real headache in callbacks, where a regular function would hand you the wrong this. Here’s the basic shape next to the old syntax:
/**
* Traditional function syntax and arrow function syntax
* @param {number} x - First number
* @param {number} y - Second number
* @returns {number} - Sum of x and y
*/
// Traditional function syntax
function add(x, y) {
return x + y;
}
// Arrow function syntax
const add = (x, y) => x + y;That same trait becomes a trap in the wrong spot. Don’t use an arrow function as an object method: with no this of its own, this won’t point at the object you expect.
Template Literals
Template literals let you drop values straight into a string with backticks and ${}, instead of gluing pieces together with +. They also span multiple lines without escape characters. Here’s the same message written both ways:
/**
* Using string concatenation and template literals
* @param {string} name - The name of the person
* @param {number} age - The age of the person
* @returns {string} - Formatted message
*/
const name = 'John';
const age = 30;
// Using string concatenation
const message = 'Hello, my name is ' + name + ' and I am ' + age + ' years old.';
// Using template literals
const message = `Hello, my name is ${name} and I am ${age} years old.`;Destructuring
Destructuring pulls values out of an array or object and assigns them to variables in one step, so you’re not writing person.name then person.age line after line. Here’s array and object destructuring side by side:
/**
* Array and object destructuring
* @param {Array} numbers - Array of numbers
* @param {Object} person - Object representing a person
*/
// Array destructuring
const numbers = [1, 2, 3];
const [a, b, c] = numbers;
// Object destructuring
const person = { name: 'John', age: 30 };
const { name, age } = person;Spread Operator
The spread operator ... expands an iterable, like an array or a string, into its individual elements. It’s handy for copying or merging arrays without a loop. One catch the shorthand skips: plain objects aren’t iterable, so spreading an object is a separate feature, added later in ES2018, that copies an object’s own enumerable properties. The syntax looks alike, which is why people mix the two up.
/**
* Merging arrays using the spread operator
* @param {Array} arr1 - First array
* @param {Array} arr2 - Second array
* @returns {Array} - Merged array
*/
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const mergedArray = [...arr1, ...arr2];Rest Operator
The rest operator uses the same ..., but it does the opposite job: it gathers leftover elements into a single array. You’ll see it most in function parameters, where it collects however many arguments a caller passes:
/**
* Function that logs all arguments passed to it
* @param {...*} args - A rest parameter that gathers all arguments
*/
function logArguments(...args) {
console.log(args);
}
logArguments(1, 2, 3, 4); // Output: [1, 2, 3, 4]Modules
Modules let you split code into separate files and pull in only what you need, which keeps a growing project organized. Any .js file can act as a module, and modern browsers and Node run them natively, so you don’t need a bundler to start.
Import/Export
To share something from a module, you export it; to use it elsewhere, you import it by name. Here’s a small math module and the file that uses it:
/**
* Example of exporting and importing functions from a module
* @param {number} x - First number
* @param {number} y - Second number
* @returns {number} - Result of the operation
*/
// math.js
export const add = (x, y) => x + y;
export const subtract = (x, y) => x - y;
// main.js
import { add, subtract } from './math.js';
console.log(add(2, 3)); // Output: 5
console.log(subtract(7, 4)); // Output: 3When a module has one main thing to hand out, a default export keeps the import name flexible:
/**
* Example of default export and import
* @param {string} name - The name of the person
* @returns {string} - Greeting message
*/
// greet.js
export default function greet(name) {
return `Hello, ${name}!`;
}
// main.js
import greet from './greet.js';
console.log(greet('John')); // Output: Hello, John!Conclusion
That’s the modern core: arrow functions, template literals, destructuring, spread and rest, and modules. You don’t need all of it at once. Pick the one that fixes the code annoying you today, and the rest will click as you hit the problems they solve.
None of this replaces understanding what the language does underneath. It’s the same JavaScript, written with less friction. Reach for these because they make your intent clearer, not because they’re new.
What’s Next?
Day 7 turns to responsive web design with JavaScript: how JS and CSS work together to build layouts that adapt to the screen and to what the user does. We’ll keep it hands-on.


