Перш за все, вважається поганою практикою продовженняObject.prototype
. Замість цього, забезпечити вашу функцію в якості функції корисності на Object
, так же , як там вже є Object.keys
, Object.assign
, Object.is
... і т.д ..
Я пропоную тут кілька рішень:
- Використання
reduce
таObject.keys
- Як (1), у поєднанні з
Object.assign
- Використання
map
та поширення синтаксису замістьreduce
- Використання
Object.entries
таObject.fromEntries
1. Використання reduce
іObject.keys
За допомогою reduce
та Object.keys
для реалізації потрібного фільтра (використовуючи синтаксис стрілки ES6 ):
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
Зауважте, що у наведеному вище коді predicate
повинна бути умова включення (всупереч умові виключення використовуваної ОП), щоб вона відповідала тому, як Array.prototype.filter
працює.
2. Як (1) у поєднанні з Object.assign
У наведеному вище рішенні оператор комами використовується в reduce
частині для повернення мутованого res
об'єкта. Звичайно, це можна записати як два твердження замість одного виразу, але останнє є більш стислим. Для того, щоб зробити це без оператора кома, ви можете використовувати Object.assign
замість цього, який дійсно повертає мутантний об'єкт:
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => Object.assign(res, { [key]: obj[key] }), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
3. Використання map
та поширення синтаксису замістьreduce
Тут ми висуваємо Object.assign
виклик з циклу, тому він робиться лише один раз, і передаємо йому окремі клавіші як окремі аргументи (використовуючи синтаксис розповсюдження ):
Object.filter = (obj, predicate) =>
Object.assign(...Object.keys(obj)
.filter( key => predicate(obj[key]) )
.map( key => ({ [key]: obj[key] }) ) );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
4. Використання Object.entries
іObject.fromEntries
Оскільки рішення переводить об'єкт у проміжний масив, а потім перетворює його назад у звичайний об'єкт, було б корисно скористатися Object.entries
(ES2017) та протилежним (тобто створити об’єкт із масиву пар ключів / значень ) з Object.fromEntries
( ES2019).
Це призводить до цього методу "одного вкладиша" на Object
:
Object.filter = (obj, predicate) =>
Object.fromEntries(Object.entries(obj).filter(predicate));
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, ([name, score]) => score > 1);
console.log(filtered);
Функція предиката отримує тут пара аргументів ключ / значення, який дещо відрізняється, але дозволяє отримати більше можливостей у логіці функції предиката.