JavaScript — мощный универсальный язык, без которого невозможно представить современную веб-разработку. В этом руководстве представлены суперхаки, которые сделают вас более эффективным и результативным разработчиком JavaScript. Каждый суперхак сопровождается подробным объяснением и кратким примером кода.

1. Использование let и const вместо var

Проблема: var обладает областью видимости функции, что может привести к ошибкам и непредсказуемому поведению.

Решение: используйте let и const, которые обладают областью видимости блока.

let count = 0;
const PI = 3.14;

Использование let и const помогает предотвратить ошибки, связанные с областью видимости, гарантируя доступность переменных только в пределах блока, в котором они определены.

2. Параметры по умолчанию

Проблема: функции могут не работать, если не указаны аргументы.

Решение: используйте параметры по умолчанию для установки резервных значений.

function greet(name = 'Guest') {
return `Hello, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"

Параметры по умолчанию гарантируют наличие у функции разумных значений по умолчанию, что предотвращает ошибки и делает код более надежным.

3. Шаблонные литералы

Проблема: конкатенация строк может быть громоздкой и чреватой ошибками.

Решение: используйте шаблонные литералы для более чистой и читабельной интерполяции строк.

const name = 'John';
const greeting = `Hello, ${name}!`;
console.log(greeting); // "Hello, John!"

Шаблонные литералы облегчают создание строк со встроенными выражениями и многострочных литералов.

4. Деструктурирующее присваивание

Проблема: извлечение значений из объектов и массивов может быть многословным.

Решение: используйте деструктурирующее присваивание, чтобы извлекать значения более лаконично.

const user = { name: 'Jane', age: 25 };
const { name, age } = user;
console.log(name, age); // "Jane" 25

Деструктурирующее присваивание позволяет легко извлекать свойства из объектов и элементы из массивов в отдельные переменные.

5. Стрелочные функции

Проблема: традиционные выражения функций могут быть многословными и не связывать this лексически.

Решение: используйте стрелочные функции для более краткого синтаксиса и лексического контекста this.

const add = (a, b) => a + b;
console.log(add(2, 3)); // 5

Стрелочные функции обеспечивают лаконичный синтаксис для выражений функций и гарантируют лексически связанный контекст this.

6. Оператор «spread»

Проблема: объединение массивов или объектов может быть громоздким.

Решение: используйте оператор «spread», чтобы легко объединять массивы и объекты.

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = […arr1, …arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]

Оператор «spread» позволяет распределить элементы массива или объекта по другому массиву или объекту.

7. Синтаксис Rest parameter

Проблема: работа с переменным количеством аргументов функции может оказаться непростой задачей.

Решение: используйте синтаксис Rest parameter, чтобы собрать все аргументы в массив.

function sum(…args) {
return args.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

Синтаксис Rest parameter позволяет обрабатывать неограниченное количество аргументов в виде массива, что делает функции более гибкими.

8. Сокращенное вычисление

Проблема: написание условных операторов может быть многословным.

Решение: используйте сокращенное вычисление, чтобы писать лаконичные условия.

const isLoggedIn = true;
const user = isLoggedIn && { name: 'Jane', age: 25 };
console.log(user); // { name: 'Jane', age: 25 }

Сокращенное вычисление использует логические операторы «&&» и «||», чтобы упростить условные выражения.

9. Опциональная цепочка

Проблема: доступ к глубоко вложенным свойствам может привести к ошибкам, если какая-либо часть цепочки является «null» или «undefined».

Решение: используйте опциональные цепочки для безопасного доступа к вложенным свойствам.

const user = { profile: { name: 'Jane' } };
const userName = user?.profile?.name;
console.log(userName); // "Jane"

Создание опциональных цепочек позволяет безопасно обращаться к вложенным свойствам без необходимости явной проверки каждого уровня цепочки на наличие значений «null» или «undefined».

10. Оператор нулевого слияния

Проблема: использование «||» для предоставления значений по умолчанию может привести к неожиданным результатам, если значение равно 0 или «».

Решение: используйте оператор нулевого слияния (??), чтобы предоставлять значения по умолчанию только в случае «null» или «undefined».

const user = { name: '', age: 0 };
const userName = user.name ?? 'Anonymous';
const userAge = user.age ?? 18;
console.log(userName); // ""
console.log(userAge); // 0

Оператор нулевого слияния позволяет предоставлять значения по умолчанию только в том случае, если левая часть является «null» или «undefined».

11. Сокращение свойств объекта

Проблема: присвоение переменных свойствам объекта может быть многократным процессом.

Решение: используйте сокращение свойств, чтобы упростить создание объектов.

const name = 'Jane';
const age = 25;
const user = { name, age };
console.log(user); // { name: 'Jane', age: 25 }

Сокращение свойств позволяет опускать имя свойства, когда оно совпадает с именем переменной, что делает код чище.

12. Динамические имена свойств

Проблема: создание объектов с динамическими именами свойств может быть многословным.

Решение: используйте вычисляемые имена свойств для динамического создания свойств объектов.

const propName = 'age';
const user = { name: 'Jane', [propName]: 25 };
console.log(user); // { name: 'Jane', age: 25 }

Вычисляемые имена свойств позволяют динамически создавать свойства объектов, используя в качестве имени свойства значение выражения.

13. Массивы «map()», «filter()» и «reduce()»

Проблема: итерация массивов для преобразования, фильтрации или накопления значений может быть утомительной.

Решение: используйте «map()», «filter()» и «reduce()» для обычных операций с массивами.

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15

Эти методы массивов обеспечивают функциональный подход к преобразованию, фильтрации и сокращению массивов, делая код более выразительным и лаконичным.

14. Строки «includes()», «startsWith()» и «endsWith()»

Проблема: проверка того, содержит ли строка подстроку, начинается с нее или заканчивается ею, может быть многословной.

Решение: используйте «includes()», «startsWith()» и «endsWith()» для более простых проверок строк.

const str = 'Hello, world!';
console.log(str.includes('world')); // true
console.log(str.startsWith('Hello')); // true
console.log(str.endsWith('!')); // true

Эти строковые методы обеспечивают простой и удобный для чтения способ проверки наличия, начала или конца подстроки.

15. Деструктурирование массивов и объектов в параметрах функций

Проблема: извлечение значений из массивов или объектов, переданных в качестве параметров функции, может быть многословным.

Решение: используйте деструктурирование в параметрах функции для прямого извлечения значений.

const user = { name: 'Jane', age: 25 };
function greet({ name, age }) {
return `Hello, ${name}! You are ${age} years old.`;
}
console.log(greet(user)); // "Hello, Jane! You are 25 years old."

Деструктурирование в параметрах функции позволяет напрямую извлекать значения из объектов или массивов, передаваемых в функцию, что делает код более лаконичным и читабельным.

16. Значения по умолчанию при деструктурировании

Проблема: обработка отсутствующих свойств при деструктурировании объектов может быть очень громоздкой.

Решение: используйте значения по умолчанию при деструктурировании, чтобы обеспечить резервные значения.

const user = { name: 'Jane' };
const { name, age = 18 } = user;
console.log(name); // "Jane"
console.log(age); // 18

Значения по умолчанию при деструктурировании позволяют предоставлять резервные значения для свойств, которые могут отсутствовать, что повышает надежность кода.

17. Object.assign()

Проблема: клонирование или объединения объектов может быть многословным и чреватым ошибками.

Решение: используйте Object.assign() для клонирования или объединения объектов.

const target = { a: 1 };
const source = { b: 2 };
const merged = Object.assign(target, source);
console.log(merged); // { a: 1, b: 2 }

Object.assign() позволяет эффективно клонировать или объединять объекты, сокращая необходимость в ручном копировании.

18. Методы массива «find()» и «findIndex()»

Проблема: поиск элемента или его индекса в массиве может быть громоздким при использовании циклов.

Решение: используйте «find()» и «findIndex()» для более читабельного кода.

const users = [
{ id: 1, name: 'Jane' },
{ id: 2, name: 'John' },
];
const user = users.find(u => u.id === 1);
console.log(user); // { id: 1, name: 'Jane' }
const index = users.findIndex(u => u.id === 1);
console.log(index); // 0

Эти методы массива обеспечивают простой способ поиска элемента или его индекса на основе условия, улучшая читаемость кода.

19. Методы массива «some()» и «every()»

Проблема: проверка соответствия некоторых или всех элементов массива условию может быть многословной.

Решение: используйте «some()» и «every()» для более чистого кода.

const numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true
const allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // false

Эти методы массива позволяют в сжатой форме проверить, удовлетворяют ли некоторые или все элементы массива какому-либо условию.

20. Методы массива «flat()» и «flatMap()»

Проблема: преобразование в плоскую структуру вложенного массива или отображение и преобразование в плоскую структуру массива может быть громоздким.

Решение: используйте «flat()» и «flatMap()» для более читабельного кода.

const nested = [1, [2, [3, [4]]]];
const flat = nested.flat(2);
console.log(flat); // [1, 2, 3, [4]]
const mapped = [1, 2, 3].flatMap(x => [x, x * 2]);
console.log(mapped); // [1, 2, 2, 4, 3, 6]

Эти методы обеспечивают простой способ преобразования в плоскую структуру вложенного массива, а также отображения и преобразования в плоскую структуру за один шаг.

21. Методы «Array.from()» и «Array.of()»

Проблема: создание массивов из итерируемых объектов или аргументов может быть многословным.

Решение: используйте «Array.from()» и «Array.of()» для более чистого кода.

const set = new Set([1, 2, 3]);
const arrFromSet = Array.from(set);
console.log(arrFromSet); // [1, 2, 3]
const arrOfNumbers = Array.of(1, 2, 3);
console.log(arrOfNumbers); // [1, 2, 3]

«Array.from()» позволяет создавать массивы из итерируемых объектов, а «Array.of()» позволяет создавать массивы из списка аргументов.

22. Деструктурирование параметров в обратных вызовах

Проблема: доступ к свойствам объектов, передаваемых в обратные вызовы, может быть многословным.

Решение: используйте деструктурирование параметров обратных вызовов, чтобы сделать код чище.

const users = [
{ id: 1, name: 'Jane' },
{ id: 2, name: 'John' },
];
users.forEach(({ id, name }) => {
console.log(`User ID: ${id}, User Name: ${name}`);
});

Деструктурирование параметров в обратном вызове позволяет напрямую обращаться к свойствам объектов, передаваемых обратному вызову, что делает код более лаконичным.

23. Опциональные коллбэк-функции 

Проблема: работа с опциональными коллбэк-функциями может быть громоздкой.

Решение: используйте сокращенное вычисление для вызова опциональных коллбэк-функций.

function fetchData(url, callback) {
fetch(url)
.then(response => response.json())
.then(data => {
callback && callback(data);
});
}

Сокращенное вычисление позволяет вызывать опциональную коллбэк-функцию только в том случае, если она предусмотрена, что делает код более надежным.

24. Промисицирование коллбэков

Проблема: преобразование функций, основанных на коллбэках, в промисы может быть громоздким.

Решение: используйте служебную функцию для промисицирования коллбэков.

function promisify(fn) {
return function (…args) {
return new Promise((resolve, reject) => {
fn(…args, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
}
const readFile = promisify(require('fs').readFile);
readFile('path/to/file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));

Промисицирование позволяет преобразовывать в промисы функции, основанные на коллбэках, что упрощает работу с синтаксисом async/await.

25. Async/Await для синхронно-подобного кода

Проблема: написание асинхронного кода с использованием промисов может быть многословным и трудночитаемым.

Решение: используйте синтаксис async/await для написания асинхронного кода в синхронном стиле.

async function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData('https://api.example.com/data');

Async/await предоставляет возможность писать асинхронный код, который выглядит и ведет себя как синхронный, что улучшает читаемость и удобство сопровождения.

26. Цепочка промисов

Проблема: последовательная обработка нескольких асинхронных операций может быть громоздкой.

Решение: цепочка промисов для обработки нескольких асинхронных операций.

fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log('Data:', data);
return fetch('https://api.example.com/more-data');
})
.then(response => response.json())
.then(moreData => {
console.log('More Data:', moreData);
})
.catch(error => {
console.error('Error:', error);
});

Цепочка промисов позволяет последовательно обрабатывать несколько асинхронных операций, что улучшает читабельность и удобство сопровождения.

27.  Метод «Promise.all» для одновременного выполнения

Проблема: одновременная обработка нескольких асинхронных операций может оказаться сложной задачей.

Решение: используйте метод «Promise.all» для обработки одновременных асинхронных операций.

const fetchData1 = fetch('https://api.example.com/data1').then(response => response.json());
const fetchData2 = fetch('https://api.example.com/data2').then(response => response.json());
Promise.all([fetchData1, fetchData2])
.then(([data1, data2]) => {
console.log('Data 1:', data1);
console.log('Data 2:', data2);
})
.catch(error => {
console.error('Error:', error);
});

Метод «Promise.all» позволяет обрабатывать несколько асинхронных операций одновременно и продолжать работу, когда все они будут завершены.

28. Функция “debounce”

Проблема: частые вызовы функций, например во время события изменения размера окна, могут снижать производительность.

Решение: используйте функцию «debounce», чтобы ограничить частоту выполнения функции.

function debounce(func, wait) {
let timeout;
return function (…args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
window.addEventListener('resize', debounce(() => {
console.log('Window resized');
}, 200));

Функция «debounce» гарантирует, что функция будет вызываться только после определенного периода неактивности, что повышает производительность.

29. Функция «throttle»

Проблема: ограничение частоты выполнения функций для событий, которые происходят часто, например прокрутка или изменение размера.

Решение: используйте функцию «throttle», чтобы ограничить частоту выполнения функции.

function throttle(func, limit) {
let lastFunc;
let lastRan;
return function (…args) {
if (!lastRan) {
func.apply(this, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if (Date.now() - lastRan >= limit) {
func.apply(this, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
window.addEventListener('scroll', throttle(() => {
console.log('Window scrolled');
}, 200));

Функция «throttle» гарантирует, что функция будет вызвана не более одного раза за определенный период. Это повышает производительность при условии наличия часто срабатывающих событий.

30. Глубокое клонирование объектов

Проблема: клонирование вложенных объектов может быть сложным и чреватым ошибками.

Решение: используйте структурированное клонирование или библиотеки вроде Lodash для глубокого клонирования объектов.

const obj = { a: 1, b: { c: 2 } };
const deepClone = JSON.parse(JSON.stringify(obj));
console.log(deepClone); // { a: 1, b: { c: 2 } }

Глубокое клонирование гарантирует копирование вложенных объектов по значению, а не по ссылке, что предотвращает непреднамеренные изменения исходного объекта.

31. Мемоизация

Проблема: повторный вызов затратных функций может снизить производительность.

Решение: используйте мемоизацию для кэширования результатов вызовов затратных функций.

function memoize(func) {
const cache = new Map();
return function (…args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = func.apply(this, args);
cache.set(key, result);
return result;
};
}
const expensiveFunction = memoize((num) => {
console.log('Computing…');
return num * 2;
});
console.log(expensiveFunction(2)); // "Comput
ing…" 4
console.log(expensiveFunction(2)); // 4

Мемоизация повышает производительность за счет кэширования результатов вызовов затратных функций и возврата кэшированного результата при последующих вызовах с теми же аргументами.

32. Каррирование функций

Проблема: создание функций с несколькими параметрами может быть громоздким процессом.

Решение: используйте каррирование для создания функций с частично применяемыми параметрами.

function curry(func) {
return function curried(…args) {
if (args.length >= func.length) {
return func.apply(this, args);
}
return function (…nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
};
}
const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6

Каррирование позволяет создавать функции, которые можно вызывать с меньшим количеством аргументов, возвращая новую функцию, принимающую оставшиеся аргументы.

33. Частичное применение

Проблема: вызовы функций с повторяющимися аргументами могут быть утомительным занятием.

Решение: используйте частичное применение, чтобы предварительно добавить некоторые аргументы в функцию.

function partial(func, …presetArgs) {
return function (…laterArgs) {
return func(…presetArgs, …laterArgs);
};
}
const multiply = (a, b, c) => a * b * c;
const double = partial(multiply, 2);
console.log(double(3, 4)); // 24

Частичное применение позволяет создавать новые функции, предварительно добавив некоторые аргументы, что делает код более гибким и пригодным для повторного использования.

34. Композиция функций

Проблема: объединение нескольких функций в одну операцию может занимать много места.

Решение: используйте композицию функций для объединения нескольких функций.

const compose = (…funcs) => (arg) =>
funcs.reduceRight((prev, fn) => fn(prev), arg);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const addThenMultiply = compose(multiply, add);
console.log(addThenMultiply(5)); // 12

Композиция функций позволяет создавать новую функцию путем объединения нескольких функций, что делает код более модульным и пригодным для повторного использования.

35. Конвейеризация функций

Проблема: применение серии функций к значению может оказаться громоздким процессом.

Решение: используйте конвейеризацию функций для последовательного применения ряда функций.

const pipe = (…funcs) => (arg) =>
funcs.reduce((prev, fn) => fn(prev), arg);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const addThenMultiply = pipe(add, multiply);
console.log(addThenMultiply(5)); // 12

Конвейеризация функций позволяет последовательно применять ряд функций к значению, что улучшает читаемость и удобство работы с кодом.

36. Самовызывающиеся функции

Проблема: выполнение функции сразу после ее определения подчас неудобно из-за громоздкости.

Решение: используйте IIFE (Immediately Invoked Function Expression — функция-выражение, вызываемая сразу после определения).

(function () {
console.log('This runs immediately!');
})();

IIFE позволяет выполнять функцию сразу после ее определения, что полезно при создании изолированных областей и предотвращения загрязнения глобального пространства имен.

37. Избегание глобальных переменных

Проблема: глобальные переменные могут привести к конфликтам и непредвиденным побочным эффектам.

Решение: используйте локальные переменные и модули, чтобы не загрязнять глобальное пространство имен.

// Использование локальных переменных
function doSomething() {
let localVariable = 'This is local';
console.log(localVariable);
}
// Использование модулей
const myModule = (function () {
let privateVariable = 'This is private';
return {
publicMethod() {
console.log(privateVariable);
},
};
})();
myModule.publicMethod(); // "This is private"

Отказ от глобальных переменных помогает предотвратить конфликты и непредвиденные побочные эффекты, делая код более модульным и удобным для сопровождения.

38. Инкапсуляция с помощью замыканий

Проблема: раскрытие внутренних деталей функции может привести к ее нецелевому использованию.

Решение: используйте замыкания для инкапсуляции внутренних деталей.

function createCounter() {
let count = 0;
return {
increment() {
count++;
return count;
},
decrement() {
count - ;
return count;
},
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1

Замыкания позволяют инкапсулировать внутренние детали и раскрывать только необходимую функциональность, повышая безопасность и удобство работы с кодом.

39. Паттерн «Module»

Проблема: организация кода в многократно используемые модули может быть сложной задачей.

Решение: используйте паттерн «Module» для создания многократно используемого и инкапсулированного кода.

const myModule = (function () {
let privateVariable = 'This is private';
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod() {
privateMethod();
},
};
})();
myModule.publicMethod(); // "This is private"

Паттерн «Module» позволяет создавать многократно используемый и инкапсулированный код, улучшая его организацию и удобство сопровождения.

40. Паттерн «Singleton»

Проблема: обеспечить создание только одного экземпляра класса может быть непросто.

Решение: используйте паттерн «Singleton» для создания единственного экземпляра.

const singleton = (function () {
let instance;
function createInstance() {
return {
name: 'Singleton Instance',
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
},
};
})();
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();
console.log(instance1 === instance2); // true

Паттерн «Singleton» гарантирует, что будет создан только один экземпляр класса, что полезно для управления общими ресурсами или конфигурациями.

41. Паттерн «Factory»

Проблема: создание объектов со сложной инициализацией может быть громоздким.

Решение: используйте паттерн «Factory» для создания объектов.

function createUser(name, role) {
return {
name,
role,
sayHello() {
console.log(`Hello, my name is ${this.name} and I am a ${this.role}`);
},
};
}
const admin = createUser('Alice', 'admin');
const user = createUser('Bob', 'user');
admin.sayHello(); // "Hello, my name is Alice and I am an admin"
user.sayHello(); // "Hello, my name is Bob and I am a user"

Паттерн «Factory» позволяет создавать объекты со сложной инициализацией гибким и многоразовым способом.

42. Паттерн «Observer»

Проблема: управление изменениями состояния и уведомление нескольких компонентов может быть сложной задачей.

Решение: используйте паттерн «Observer» для управления изменениями состояния и оповещения наблюдателей.

function Subject() {
this.observers = [];
}
Subject.prototype = {
subscribe(observer) {
this.observers.push(observer);
},
unsubscribe(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
},
notify(data) {
this.observers.forEach((observer) => observer.update(data));
},
};
function Observer(name) {
this.name = name;
}
Observer.prototype.update = function (data) {
console.log(`${this.name} received data: ${data}`);
};
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('New data available'); // "Observer 1 received data: New data available" "Observer 2 received data: New data available"

Паттерн «Observer» позволяет управлять изменениями состояния и уведомлять несколько наблюдателей, что улучшает организацию и сопровождаемость кода.

43. Делегирование событий

Проблема: добавление слушателей событий к нескольким элементам может снизить производительность.

Решение: используйте делегирование событий для их эффективного управления.

document.getElementById('parent').addEventListener('click', (event) => {
if (event.target && event.target.matches('button.className')) {
console.log('Button clicked:', event.target.textContent);
}
});

Делегирование событий позволяет эффективно ими управлять, добавляя один слушатель событий к общему родительскому элементу и обрабатывая события для нескольких дочерних элементов.

44. Избегание использования «eval()»

Проблема: использование «eval()» может привести к уязвимостям в системе безопасности и проблемам с производительностью.

Решение: вместо «eval()» используйте более безопасные альтернативы.

// Избегайте
const code = 'console.log("Hello, world!")';
eval(code); // "Hello, world!"
// Используйте более безопасную альтернативу
const func = new Function('console.log("Hello, world!")');
func(); // "Hello, world!"

Отказ от использования «eval()» помогает предотвратить уязвимости в системе безопасности и проблемы с производительностью, делая код более безопасным и эффективным.

45. Использование “for…of” для итерации

Проблема: итерация массивов с помощью «for…in» чревата ошибками.

Решение: используйте «for…of» для итерации по массивам и другим итерируемым объектам.

const arr = [1, 2, 3, 4, 5];
for (const value of arr) {
console.log(value);
}
// 1
// 2
// 3
// 4
// 5

Использование «for…of» обеспечивает простой и безопасный способ итерации.

Надеюсь, в этом руководстве нашлось что-то полезное для вас — будь вы опытным разработчиком, желающим повысить уровень своего мастерства, или новичком, стремящимся освоить новые знания. Погрузитесь в него и откройте для себя секреты овладения JavaScript на высокопрофессиональном уровне!

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Amit Mishra: 45 JavaScript Super Hacks Every Developer Should Know

Предыдущая статьяAndroid/Kotlin/Jetpack Compose: обработка push-уведомлений