← Назад к вопросам

Как сравниваются массивы в JavaScript?

2.0 Middle🔥 201 комментариев
#JavaScript Core#Браузер и сетевые технологии

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Сравнение массивов в JavaScript: полное руководство

В JavaScript сравнение массивов — одна из самых частых проблем, с которыми сталкиваются разработчики. Основная сложность заключается в том, что массивы в JS являются объектами, и их сравнение имеет специфические особенности.

Операторы сравнения (== и ===) и их поведение

При использовании операторов == (нестрогое равенство) или === (строгое равенство) для сравнения двух массивов, JavaScript сравнивает ссылку на объект в памяти, а не его содержимое.

// Прямое сравнение всегда возвращает false, даже при одинаковом содержимом
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];

console.log(arr1 == arr2);  // false
console.log(arr1 === arr2); // false

// Сравнение с той же самой ссылкой даст true
const arr3 = arr1;
console.log(arr1 === arr3); // true

Основные методы сравнения содержимого массивов

1. Поэлементное сравнение (цикл или методы массивов)

Самый надёжный способ — сравнить каждый элемент отдельно:

function arraysEqual(arr1, arr2) {
  if (arr1.length !== arr2.length) return false;
  
  for (let i = 0; i < arr1.length; i++) {
    if (arr1[i] !== arr2[i]) return false;
  }
  
  return true;
}

// Использование
console.log(arraysEqual([1, 2, 3], [1, 2, 3])); // true
console.log(arraysEqual([1, 2, 3], [1, 2, 4])); // false

2. Использование методов массивов (every)

Более современный подход с использованием метода every():

function arraysEqual(arr1, arr2) {
  return arr1.length === arr2.length && 
         arr1.every((value, index) => value === arr2[index]);
}

// Сокращённая версия
const areEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);

3. Преобразование в строку (JSON.stringify)

Популярный, но имеющий ограничения метод:

const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];

console.log(JSON.stringify(arr1) === JSON.stringify(arr2)); // true

Важные ограничения этого подхода:

  • Порядок элементов важен: [1, 2, 3] не равно [1, 3, 2]
  • Не работает с циклическими ссылками
  • Может не учитывать специальные типы (NaN, undefined, null в определённых позициях)
  • Приводит к проблемам с датами (они преобразуются в строки)

Особые случаи и подводные камни

Сравнение многомерных массивов

Для вложенных структур требуется рекурсивное сравнение:

function deepArraysEqual(arr1, arr2) {
  if (arr1.length !== arr2.length) return false;
  
  for (let i = 0; i < arr1.length; i++) {
    const val1 = arr1[i];
    const val2 = arr2[i];
    
    if (Array.isArray(val1) && Array.isArray(val2)) {
      if (!deepArraysEqual(val1, val2)) return false;
    } else if (val1 !== val2) {
      return false;
    }
  }
  
  return true;
}

console.log(deepArraysEqual([1, [2, 3]], [1, [2, 3]])); // true

Сравнение с объектами и специальными значениями

// Особенности сравнения
const arr1 = [NaN, null, undefined];
const arr2 = [NaN, null, undefined];

// JSON.stringify не работает с NaN
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)); // false

// При циклическом сравнении NaN !== NaN
console.log(arr1[0] === arr2[0]); // false

Производительность и выбор метода

  1. Для простых одномерных массивов — используйте every() или простой цикл
  2. Для глубокого сравнения — напишите рекурсивную функцию или используйте готовые библиотеки
  3. Избегайте JSON.stringify для сложных структур и там, где важна производительность

Библиотечные решения

В реальных проектах часто используют готовые утилиты:

// Lodash
_.isEqual(arr1, arr2);

// Underscore.js
_.isEqual(arr1, arr2);

Практические рекомендации

  • Всегда проверяйте длину массивов перед поэлементным сравнением
  • Учитывайте типы элементов1 (число) не равно '1' (строка)
  • Помните о мутациях — если вы изменяете один массив, ссылки на него тоже изменятся
  • Для глубокого клонирования и сравнения используйте библиотеки или тщательно тестируйте свои решения

В 90% случаев достаточно простого поэлементного сравнения с проверкой длины. Главное — чётко понимать, что в JavaScript два отдельных массива никогда не будут равны при использовании операторов == или ===, даже если они содержат одинаковые элементы в одинаковом порядке. Это фундаментальное свойство работы с объектами в языке.