About us Guides Projects Contacts
Админка
please wait

JavaScript has evolved dramatically since ES6 (2015), adding features that make code more readable, maintainable, and powerful. Understanding modern JavaScript—from destructuring to async/await—is essential for writing professional code. This guide covers essential modern JavaScript features from a senior developer's perspective.

Why Modern JavaScript Matters

Modern JavaScript enables:

  1. Cleaner Code: Less boilerplate, more expressive
  2. Fewer Bugs: Features that prevent common errors
  3. Better Performance: Optimized language features
  4. Async Handling: Elegant asynchronous programming
  5. Functional Patterns: First-class function support

Variable Declarations

let and const

// const: Cannot be reassigned (use by default)
const API_URL = 'https://api.example.com';
const config = { timeout: 5000 };
// Can modify properties of const objects
config.timeout = 10000; // OK
// config = {}; // Error: Cannot reassign
// let: Can be reassigned (use when needed)
let count = 0;
count = 1; // OK
// Block scoping
if (true) {
const scoped = 'only here';
let alsoScoped = 'only here too';
}
// scoped and alsoScoped are not accessible here
// var hoisting problems (avoid var)
console.log(x); // undefined (hoisted)
var x = 5;

Destructuring

Object Destructuring

const user = {
name: 'John',
email: '[email protected]',
address: {
city: 'NYC',
zip: '10001'
}
};
// Basic destructuring
const { name, email } = user;
console.log(name); // 'John'
// Rename variables
const { name: userName, email: userEmail } = user;
console.log(userName); // 'John'
// Default values
const { role = 'user' } = user;
console.log(role); // 'user' (doesn't exist in user)
// Nested destructuring
const { address: { city, zip } } = user;
console.log(city); // 'NYC'
// Rest operator
const { name: n, ...rest } = user;
console.log(rest); // { email: '...', address: {...} }
// Function parameters
function greet({ name, email }) {
console.log(`Hello ${name} (${email})`);
}
greet(user);
// With defaults in parameters
function createUser({ name = 'Anonymous', role = 'user' } = {}) {
return { name, role };
}
createUser(); // { name: 'Anonymous', role: 'user' }

Array Destructuring

const colors = ['red', 'green', 'blue', 'yellow'];
// Basic array destructuring
const [first, second] = colors;
console.log(first); // 'red'
// Skip elements
const [, , third] = colors;
console.log(third); // 'blue'
// Rest operator
const [primary, ...others] = colors;
console.log(others); // ['green', 'blue', 'yellow']
// Default values
const [a, b, c, d, e = 'purple'] = colors;
console.log(e); // 'purple'
// Swap variables
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 1
// Function returns
function getCoordinates() {
return [40.7128, -74.0060];
}
const [lat, lng] = getCoordinates();

Spread Operator

Arrays

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// Combine arrays
const combined = [...arr1, ...arr2];
// [1, 2, 3, 4, 5, 6]
// Copy array (shallow)
const copy = [...arr1];
// Add elements
const withExtra = [0, ...arr1, 4];
// [0, 1, 2, 3, 4]
// Convert iterable to array
const chars = [...'hello'];
// ['h', 'e', 'l', 'l', 'o']
// Function arguments
function sum(a, b, c) {
return a + b + c;
}
sum(...arr1); // 6

Objects

const defaults = { theme: 'light', lang: 'en' };
const userPrefs = { theme: 'dark' };
// Merge objects (later properties win)
const settings = { ...defaults, ...userPrefs };
// { theme: 'dark', lang: 'en' }
// Copy object (shallow)
const copy = { ...defaults };
// Add/override properties
const extended = { ...defaults, fontSize: 16 };
// Conditional spreading
const extra = true;
const obj = {
required: 'value',
...(extra && { optional: 'included' })
};

Template Literals

const name = 'John';
const age = 30;
// String interpolation
const greeting = `Hello, ${name}! You are ${age} years old.`;
// Expressions in templates
const message = `Next year you'll be ${age + 1}`;
// Multi-line strings
const html = `
<div class="card">
<h2>${name}</h2>
<p>Age: ${age}</p>
</div>
`;
// Tagged templates
function highlight(strings, ...values) {
return strings.reduce((result, str, i) => {
const value = values[i] ? `<strong>${values[i]}</strong>` : '';
return result + str + value;
}, '');
}
const highlighted = highlight`Hello ${name}, you are ${age}!`;
// 'Hello <strong>John</strong>, you are <strong>30</strong>!'

Arrow Functions

// Basic syntax
const add = (a, b) => a + b;
// Single parameter (no parentheses needed)
const double = x => x * 2;
// No parameters
const getRandom = () => Math.random();
// Multi-line (need braces and return)
const calculate = (a, b) => {
const sum = a + b;
const product = a * b;
return { sum, product };
};
// Return object literal (wrap in parentheses)
const createUser = (name, email) => ({ name, email });
// Array methods
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
// Lexical this (no own this binding)
const obj = {
name: 'Object',
greet() {
// Arrow function inherits this from greet()
setTimeout(() => {
console.log(this.name); // 'Object'
}, 100);
}
};

Array Methods

const users = [
{ id: 1, name: 'John', age: 30 },
{ id: 2, name: 'Jane', age: 25 },
{ id: 3, name: 'Bob', age: 35 }
];
// map: Transform each element
const names = users.map(u => u.name);
// ['John', 'Jane', 'Bob']
// filter: Keep matching elements
const adults = users.filter(u => u.age >= 30);
// [{ id: 1, ... }, { id: 3, ... }]
// find: Get first matching element
const john = users.find(u => u.name === 'John');
// { id: 1, name: 'John', age: 30 }
// findIndex: Get index of first match
const johnIndex = users.findIndex(u => u.name === 'John');
// 0
// some: Check if any match
const hasAdult = users.some(u => u.age >= 18);
// true
// every: Check if all match
const allAdults = users.every(u => u.age >= 18);
// true
// reduce: Accumulate to single value
const totalAge = users.reduce((sum, u) => sum + u.age, 0);
// 90
// Chaining
const result = users
.filter(u => u.age >= 30)
.map(u => u.name)
.sort();
// ['Bob', 'John']
// includes
const hasJohn = names.includes('John'); // true
// flat: Flatten nested arrays
const nested = [[1, 2], [3, 4], [5]];
const flat = nested.flat(); // [1, 2, 3, 4, 5]
// flatMap: map + flat
const sentences = ['Hello World', 'Goodbye World'];
const words = sentences.flatMap(s => s.split(' '));
// ['Hello', 'World', 'Goodbye', 'World']

Object Shorthand

const name = 'John';
const age = 30;
// Property shorthand
const user = { name, age };
// Same as: { name: name, age: age }
// Method shorthand
const obj = {
greet() {
return 'Hello';
},
// Same as: greet: function() { return 'Hello'; }
};
// Computed property names
const key = 'dynamicKey';
const dynamic = {
[key]: 'value',
[`${key}_backup`]: 'backup'
};
// { dynamicKey: 'value', dynamicKey_backup: 'backup' }

Optional Chaining and Nullish Coalescing

const user = {
name: 'John',
address: {
city: 'NYC'
}
};
// Optional chaining (?.)
const zip = user?.address?.zip; // undefined (no error)
const country = user?.address?.country?.code; // undefined
// Without optional chaining (old way)
const zipOld = user && user.address && user.address.zip;
// With arrays
const first = users?.[0]?.name;
// With functions
const result = obj?.method?.();
// Nullish coalescing (??)
// Returns right side only if left is null or undefined
const value = null ?? 'default'; // 'default'
const zero = 0 ?? 'default'; // 0 (0 is not nullish)
const empty = '' ?? 'default'; // '' (empty string is not nullish)
// Compare with || (falsy check)
const valueOr = null || 'default'; // 'default'
const zeroOr = 0 || 'default'; // 'default' (0 is falsy!)
// Combining
const setting = config?.theme ?? 'light';

Async/Await

// Basic async function
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
const user = await response.json();
return user;
}
// Error handling
async function fetchUserSafe(id) {
try {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Failed to fetch user:', error);
return null;
}
}
// Parallel execution
async function fetchAll() {
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
]);
return { users, posts };
}
// Sequential execution
async function fetchSequential() {
const user = await fetchUser(1);
const posts = await fetchPosts(user.id); // Depends on user
return { user, posts };
}
// Async arrow function
const getUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
return response.json();
};

Modules (Import/Export)

// Named exports (utils.js)
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class Calculator { }
// Default export (User.js)
export default class User {
constructor(name) {
this.name = name;
}
}
// Named imports
import { PI, add } from './utils.js';
// Rename imports
import { add as sum } from './utils.js';
// Import all as namespace
import * as utils from './utils.js';
utils.add(1, 2);
// Default import
import User from './User.js';
// Mixed
import User, { helper } from './User.js';
// Dynamic import
const module = await import('./heavy-module.js');

Key Takeaways

  1. Use const by default: Only use let when reassignment is needed
  2. Destructure early: Clean up function parameters and assignments
  3. Spread for immutability: Create new arrays/objects instead of mutating
  4. Arrow functions for callbacks: Cleaner syntax, lexical this
  5. Optional chaining for safety: Avoid "cannot read property of undefined"
  6. async/await over promises: More readable async code

Modern JavaScript features aren't just syntactic sugar—they enable patterns that make code more robust and maintainable.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive