JS ES6 / 2015
In this page:
let and const: Block Scoping
let and const introduced true block scoping (limited to the nearest { }), fixing var's confusing function-scoping and hoisting behavior -- const additionally prevents reassignment, making the programmer's intent (this value will not change) explicit in the code itself.
Note: Default to const for any variable that will not be reassigned, and let for one that will -- both largely replace var in modern code.
Warning: const prevents reassigning the variable itself, but does not make an object or array it holds immutable -- its properties or elements can still change.
Example: let and const: Block Scoping
{
let blockScoped = "inside";
const fixed = "cannot reassign";
console.log(blockScoped, fixed);
}
// console.log(blockScoped); // ReferenceError, not visible out here
Arrow Functions and Template Literals
Arrow functions (x => x * 2) offer a shorter function syntax and inherit this from their surrounding scope rather than defining their own, and template literals (Hello ${name}) let you embed expressions directly inside a string using backticks, replacing awkward string concatenation.
Note: Use template literals by default for any string that includes a variable or expression, since they read more clearly than + concatenation.
Warning: Arrow functions' inherited this behavior is a feature, not a bug, but it means they are not suitable as a direct replacement everywhere a regular function was used, particularly for object methods relying on their own this.
Example: Arrow Functions and Template Literals
const double = x => x * 2;
const name = "Sam";
console.log(double(5), `Hello ${name}`);
Destructuring and Default Parameters
Destructuring lets you unpack values from an array or object into individual variables in one line (const { name, age } = person), and default parameters let a function parameter fall back to a specified value automatically when the caller does not provide one.
Note: Use destructuring when extracting several properties from the same object or array, since it reads more clearly than several separate property-access lines.
Warning: Destructuring a property that does not exist on the source object produces undefined rather than an error, which combines naturally with default values for safe extraction.
Example: Destructuring and Default Parameters
const person = { name: "Sam", age: 30 };
const { name, age } = person;
function greet(greeting = "Hello") { console.log(greeting); }
greet();
console.log(name, age);
Classes and Promises
ES6's class keyword provides cleaner, more familiar syntax for defining constructor functions and their prototype methods (JavaScript's existing inheritance model underneath), and the Promise object standardized handling asynchronous operations, replacing inconsistent, ad-hoc callback patterns that came before it.
Note: Learn ES6 classes as a cleaner syntax over JavaScript's existing prototype system, not as an entirely new type of object model borrowed from another language.
Warning: A Promise-based function still needs proper error handling (.catch() or try/catch with await) -- Promises standardize the pattern, but do not eliminate the need to handle failures.
Example: Classes and Promises
class Animal {
constructor(name) { this.name = name; }
}
new Promise(resolve => resolve("done")).then(v => console.log(v));
console.log(new Animal("Rex").name);
Modules: import and export
ES6 introduced a native module system -- export makes a variable, function, or class available to other files, and import brings it into another file -- standardizing how JavaScript code is split across multiple files, something the language had no built-in mechanism for before.
Note: Use ES6 modules (with type="module" on your script tag, or a bundler in larger projects) as the standard way to organize code across multiple files in modern JavaScript.
Warning: A script loaded with type="module" runs in strict mode automatically and has its own separate scope, which can surprise code relying on older global-script assumptions.
Example: Modules: import and export
// math.js: export function add(a, b) { return a + b; }
// main.js:
import { add } from './math.js';
console.log(add(2, 3));
- Assuming class syntax means JavaScript gained true classical inheritance like Java or C++ -- ES6 classes are syntax sugar over JavaScript's existing prototype-based inheritance, not a fundamentally new object model.
- Using var out of habit in new code, missing the block-scoping benefits let and const were specifically introduced to provide.
- Forgetting that arrow functions handle the this keyword differently from regular functions, which can cause bugs when converting older code to arrow function syntax carelessly.
- let and const introduced proper block scoping, replacing var's function-scoping quirks for most new code.
- Arrow functions, template literals, destructuring, and default parameters are widely-used ES6 syntax improvements.
- Promises and the module system (import/export) gave JavaScript standardized tools for asynchronous code and code organization.
ES6/ES2015 features are supported natively in every browser released since roughly 2016, and are effectively universal in current browsers.
Chapter Quiz — Complete all 9 topics to unlock
0/9 topics done
Complete these topics first: