给对象添加filter方法

给对象添加 filter 方法

es6 中数组类型拥有 filter 方法,但有时我们会需要让对象类型也使用这个方法,例如有这么一个对象:

1
2
3
const person = {
name: "star",
}

那么是否可以在Object.prototype上增加 filter 方法用来给所有对象使用呢?

1
2
3
4
5
6
7
8
9
Object.prototype.filter = function (predicate) {
const result = {}
for (key in this) {
if (this.hasOwnProperty(key) && !predicate(this[key])) {
result[key] = this[key]
}
}
return result
}

答案是不允许的,因为所有引用类型的原型链上都有Object.prototype,所以这会导致这些类型都被莫名奇妙地增加了这个方法。所以,在Object上新增方法更加合适,例如:

  • 使用Object.keysreduce实现
1
2
3
4
5
6
7
8
Object.filter = (obj, predicate) => {
Ojbect.keys(obj)
.filter((key) => predicate(obj[key]))
.reduce((res, key) => {
res[key] = obj[key]
return res
}, {})
}
  • 使用Ojbect.assign展开运算符和Object.map代替上面的reduce
1
2
3
4
5
Object.filter = (obj, predicate) =>
Object.assign(
...Ojbect.keys(obj)
.filter(key => predicate(obj[key]))
.map(key => { [key]: obj[key] }))
  • 使用Object.entriesObject.fromEntries
1
2
Object.filter = (obj, predicate) =>
Object.fromEntries(Object.entries(obj).filter(keyValue => predicate(keyValue[1])))

注意:Object.fromEntries属于ES2019,有兼容性问题。