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 шт):
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);