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 на высокопрофессиональном уровне!
Читайте также:
- Возможности контроля в JavaScript: методы AbortSignal.timeout() и AbortSignal.any()
- Секреты оператора delete
- Создание сайдбара с помощью HTML, CSS и JavaScript
Читайте нас в Telegram, VK и Дзен
Перевод статьи Amit Mishra: 45 JavaScript Super Hacks Every Developer Should Know