Теоретическая часть вопроса
По сути нам нужно сравнить Наборы (Set) элементов двух Массивов(Array). Я специально создам массивы с повторяющимися значениями. Зачем? Потому что в реальной жизни скорее всего будут дубли элементов в пределах одного массива.
В решении этой задачи нас будут интересовать только САМИ ЗНАЧЕНИЯ, а не их последовательности. Сравнивать мы будем содержимое.
var massiv1 = [1,2,3,3,4,4,4,5,6,7,8,9,9]
var massiv2 = [1,1,3,3,4,4,4,6,6,7,8,10,11]
Наборы(Set) оставят нам уникальные значения в массивах, чтобы мы не повторяли процедуру переборов по несколько раз для одинаковых элементов массивов. Их может быть десятки тысяч в реальных проектах. Это нагрузка на систему.
var set1 = Array.from(new Set(massiv1))
var set2 = Array.from(new Set(massiv2))
Набор возвращает объект, а нам нужен массив. Конвертируем наборы в массивы:

Логика такая! Если значение из первого массива встречается во втором массиве, тогда идём дальше на следующий элемент. Если элементы совпадают — значит это не «РАЗЛИЧИЯ», а «ОДИНАКОВОСТИ».
Мы должны отобрать все различия и вернуть их в качестве отдельного массива. Эта операция похожа на «вычитание массивов» — элементы одного массива вычитаются из другого массива. Жаль, что для вычитания не придумали встроенного в язык метода, ходя для сложения он есть.
Решение
Будем использовать метод filter() прототипов объекта Array. Фильтр будет создавать нам новый массив. В качестве параметра будем передавать функцию, которая будет возвращаться нам булев тип данных — true или false. Фильтр будет смотреть на истину или ложь, и потом принимать решение сохранить этот элемент в новом массиве или нет.
И с этого момента у нас есть два пути решения задачи.
Способ № 1 — filter + includes
Логика работы includes возвращает нам истину, если находит элемент в массиве. Например, если filter кидает нам первый элемент первого массива (1), то includes будет искать его во втором массиве, а когда найдёт — вернёт true. filter в первую итерацию посмотрит на true и закинет значение 1 в новый массив. Такой вариант нам не подходит потому, что так мы получим набор общих элементов, которые встречаются и в первом, и во втором массивах.
Вернёт общие с первым набором элементы. Те из первого, которые встречаются во втором наборе.
var filter1 = set1.filter(i => set2.includes(i))
Вернёт общие со вторым набором элементы. Те из второго, которые встречаются в первом наборе.
var filter2 = set2.filter(i => set1.includes(i))
При любой вариации вернёт ОБЩИЕ элементы.
[1, 3, 4, 6, 7, 8]
ВНИМАНИЕ! Но если мы добавим отрицание в работу метода includes(), то будем получать НУЖНЫЙ НАМ РЕЗУЛЬТАТ:
Вернёт элементы, которые не встречаются во втором наборе (массиве)
var test1 = set1.filter(i => !set2.includes(i))
Вернёт элементы, которые не встречаются в первом наборе (массиве)
var test2 = set2.filter(i => !set1.includes(i))

Можно сразу создать массив из элементов «РАЗНИЦЫ»:
[...set1.filter(i => !set2.includes(i)), ...set2.filter(i => !set1.includes(i))]
Функция для работы
Разница между двумя массивами:
function arrayDiff(a, b) { return [ ...a.filter(x => !b.includes(x)), ...b.filter(x => !a.includes(x)) ]; }
Разница между несколькими массивами:
function arrayDiff(...arrays) { return [].concat(...arrays.map( (arr, i) => { const others = arrays.slice(0); others.splice(i, 1); const unique = [...new Set([].concat(...others))]; return arr.filter(x => !unique.includes(x)); })); }
Способ № 2 — filter + indexOf
Вернёт те, которых нет во втором
var fil1 = set1.filter(i => set2.indexOf(i) < 0) [2, 5, 9]
Вернёт те, которых нет в первом
var fil2 = set2.filter(i => set1.indexOf(i) < 0) [10, 11]
Итог
Существует целое направление задач, таких как:
- объединение
- пересечение
- разность
Они схожи по своему смыслу т. к. взаимодействуют со множествами.
Информационные ссылки
JavaScript — Массивы(Array) — https://efim360.ru/javascript-massivy-array/
JavaScript — Наборы(Set) —
ECMAScript — Living Standard — Set Objects — https://tc39.es/ecma262/#sec-set-objects
ECMAScript — Living Standard — Array Objects — https://tc39.es/ecma262/#sec-array-objects