fix(filterFilter): correctly handle deep expression objects

Previously, trying to use a deep expression object (i.e. an object whose properties can be objects themselves) did not work correctly. This commit refactors `filterFilter`, making it simpler and adding support for filtering collections of arbitrarily deep objects.

Closes #9698

---
<sub>
BTW, I used "non-IE8" stuff (like `Array.prototype.some/every`) for the sake of conciseness and clarity, so this is not directly back-portable to 1.2.x. If there is interest, I can create a IE8 compatible version (using `for-loops` etc).
</sub>
> B) When specifying expression as a string (which gets internally converted to {$: '...'}, should the new object inherit from Object ?

`createMap()` is fine for these, in cases where we create the object.

> If the expression object and/or the item has an own property that is a function, comparing against that property should always return false (even if the value to compare against is the exact same function or an "identical" function) ?
> What should happen with inherited properties that are functions ? Consider that item and expression could have different prototypes.

I think we should just not have a predicate for properties that are functions, regardless of where they are in the prototype chain