filter вместо параметра callback Set.prototype.has

Никак не понимаю как работает этот код

function getCommon(a, b) {
  const isObject = o => typeof o === 'object';

  return Object.fromEntries(Object
      .keys(a)
      .filter(Set.prototype.has, new Set(Object.keys(b)))
      .filter(k => a[k] === b[k] || isObject(a[k]) && isObject(b[k]))
      .map(k => [k, isObject(a[k]) ? getCommon(a[k], b[k]) : a[k]])
  );
}

console.log(getCommon({ a: 3, b: { x: 7 } }, { a: 4, b: { x: 7, y: 10 } }));

Результат

{
  "b": {
    "x": 7
  }
}

А если точнее это строка

.filter(Set.prototype.has, new Set(Object.keys(b)))

Я понимаю что filter ждет первым аргументом функцию, а Set.prototype.has и есть функция, но тогда почему не работает этот мой код?

const a = [4,5,99,2];

const b = a.filter(Set.prototype.has) // Ошибкa 

Ответы (1 шт):

Автор решения: vsemozhebuty

Set.prototype.has ожидает выполнения как метод экземпляра Set. То есть внутри него this должно равняться экземпляру Set. Что и достигается в вашем первом примере через второй параметр метода filter(), который задаёт this для функции-первого параметра. Чтобы ваш второй пример работал, нужно добавить второй параметр — экземпляр Set, в котором будет проверяться наличие элементов из фильтруемого массива:

const a = [4, 5, 99, 2];

const b = a.filter(Set.prototype.has, new Set([2, 4]));

console.log(b);

Того же эффекта можно достигнуть похожим способом:

const a = [4, 5, 99, 2];

const b = a.filter(Set.prototype.has.bind(new Set([2, 4])));

console.log(b);

Или таким:

const a = [4, 5, 99, 2];

const b = a.filter(function (num) { return this.has(num); }, new Set([2, 4]));

console.log(b);

Хотя это довольно вычурные способы. Наверное, понятнее для читателя было бы так:

const a = [4, 5, 99, 2];

const set = new Set([2, 4]);
const b = a.filter(num => set.has(num));

console.log(b);

→ Ссылка