Ответы на популярные вопросы по языку JavaScript
Основные вопросы по JavaScript
Как проверить, что переменная является массивом?
Наиболее эффективный способ - использовать статический метод Array.isArray(). Он работает корректно в любом контексте, включая iframe.
console.log(Array.isArray([1,2,3])); // true
console.log(Array.isArray({0:1})); // falseответы javascript (вопросы и ответы по javascript)
Другие варианты проверки
Использование instanceof
console.log([1,2] instanceof Array); // true
Этот способ может дать ложный результат, если массив создан в другом фрейме.
Через Object.prototype.toString
console.log(Object.prototype.toString.call([1,2])); // [object Array]
Работает надёжно, но синтаксически громоздок.
Типичные проблемы
- Оператор
typeofдля массива вернёт"object", а не"array". - Сравнение через
instanceofне работает между разными глобальными объектами (например, iframe).
Как клонировать объект или массив?
Для глубокого клонирования без потери типов (Date, RegExp, Map, Set) применяется structuredClone(). Этот метод поддерживается в современных браузерах.
const original = { a: 1, b: { c: 2 } };
const clone = structuredClone(original);
clone.b.c = 5;
console.log(original.b.c); // 2
Поверхностное клонирование
Использование spread-оператора:
const arr = [1,2,3];
const copy = [...arr];
Или Object.assign():
const objCopy = Object.assign({}, original);
Глубокое клонирование через JSON
const deepClone = JSON.parse(JSON.stringify(original));
Этот способ не сохраняет функции, undefined, Symbol и специальные типы (Date становится строкой).
Ошибки при клонировании
JSON.parse/stringifyвызовет ошибку при циклических ссылках.- Spread копирует только первый уровень, вложенные объекты остаются ссылками.
Как удалить дубликаты из массива?
Для массивов примитивов самый простой и быстрый способ - использовать Set.
const arr = [1,2,2,3,3,4];
const unique = [...new Set(arr)];
console.log(unique); // [1,2,3,4]
Альтернативные способы
С использованием filter и indexOf
const unique = arr.filter((item, index) => arr.indexOf(item) === index);
Метод менее производительный для больших массивов.
С использованием reduce
const unique = arr.reduce((acc, elem) => {
if (!acc.includes(elem)) acc.push(elem);
return acc;
}, []);
Особенности
- Set удаляет только примитивы, для объектов сравнение идёт по ссылке.
- Метод
indexOfиспользует строгое сравнение, что может не подойти для NaN (NaN != NaN).
Рекурсивная функция глубокого клонирования
function deepClone(obj, hash = new WeakMap()) {
if (Object(obj) !== obj) return obj; // примитивы
if (hash.has(obj)) return hash.get(obj); // циклические
const result = Array.isArray(obj) ? [] : {};
hash.set(obj, result);
for (const key of Object.keys(obj)) {
result[key] = deepClone(obj[key], hash);
}
return result;
}
const a = { b: { c: 1 } };
const cloned = deepClone(a);
cloned.b.c = 2;
console.log(a.b.c); // 1
Клонирование с сохранением прототипа
class Person {
constructor(name) { this.name = name; }
}
const p = new Person('Alice');
const cloned = Object.assign(Object.create(Object.getPrototypeOf(p)), p);
console.log(cloned instanceof Person); // true
Глубокое клонирование с structuredClone (обработка циклических ссылок)
const obj = { x: 1 };
obj.self = obj;
const cloned = structuredClone(obj);
console.log(cloned.self === cloned); // true
console.log(cloned.self === obj); // false
Клонирование специализированных типов
const map = new Map([[1, 'a'], [2, 'b']]);
const clonedMap = structuredClone(map);
console.log(clonedMap.get(1)); // 'a'
const date = new Date('2025-01-01');
const clonedDate = structuredClone(date);
console.log(clonedDate instanceof Date); // true
console.log(clonedDate.getTime() === date.getTime()); // true
const regex = /test/gi;
const clonedRegex = structuredClone(regex);
console.log(clonedRegex instanceof RegExp); // true
Использование библиотеки Lodash
const _ = require('lodash');
const complex = { a: { b: new Set([1,2]) } };
const deep = _.cloneDeep(complex);
console.log(deep.a.b instanceof Set); // true