@@ -120,16 +120,20 @@ function filterFilter() {
120
120
if ( ! isArray ( array ) ) return array ;
121
121
122
122
var predicateFn ;
123
+ var matchAgainstAnyProp ;
123
124
124
125
switch ( typeof expression ) {
125
126
case 'function' :
126
127
predicateFn = expression ;
127
128
break ;
128
129
case 'boolean' :
129
130
case 'number' :
130
- case 'object' :
131
131
case 'string' :
132
- predicateFn = createPredicateFn ( expression , comparator ) ;
132
+ matchAgainstAnyProp = true ;
133
+ //jshint -W086
134
+ case 'object' :
135
+ //jshint +W086
136
+ predicateFn = createPredicateFn ( expression , comparator , matchAgainstAnyProp ) ;
133
137
break ;
134
138
default :
135
139
return array ;
@@ -140,51 +144,56 @@ function filterFilter() {
140
144
}
141
145
142
146
// Helper functions for `filterFilter`
143
- function createPredicateFn ( expression , comparator ) {
147
+ function createPredicateFn ( expression , comparator , matchAgainstAnyProp ) {
144
148
var predicateFn ;
145
149
146
150
if ( comparator === true ) {
147
151
comparator = equals ;
148
152
} else if ( ! isFunction ( comparator ) ) {
149
153
comparator = function ( actual , expected ) {
154
+ if ( isObject ( actual ) || isObject ( expected ) ) {
155
+ // Prevent an object to be considered equal to a string like `'[object'`
156
+ return false ;
157
+ }
158
+
150
159
actual = lowercase ( '' + actual ) ;
151
160
expected = lowercase ( '' + expected ) ;
152
161
return actual . indexOf ( expected ) !== - 1 ;
153
162
} ;
154
163
}
155
164
156
165
predicateFn = function ( item ) {
157
- return deepCompare ( item , expression , comparator ) ;
166
+ return deepCompare ( item , expression , comparator , matchAgainstAnyProp ) ;
158
167
} ;
159
168
160
169
return predicateFn ;
161
170
}
162
171
163
- function deepCompare ( actual , expected , comparator , keyWasDollar ) {
172
+ function deepCompare ( actual , expected , comparator , matchAgainstAnyProp ) {
164
173
var actualType = typeof actual ;
165
174
var expectedType = typeof expected ;
166
175
167
176
if ( ( expectedType === 'string' ) && ( expected . charAt ( 0 ) === '!' ) ) {
168
- return ! deepCompare ( actual , expected . substring ( 1 ) , comparator ) ;
177
+ return ! deepCompare ( actual , expected . substring ( 1 ) , comparator , matchAgainstAnyProp ) ;
169
178
} else if ( actualType === 'array' ) {
170
179
// In case `actual` is an array, consider it a match
171
- // if any of it's items matches `expected`
180
+ // if ANY of it's items matches `expected`
172
181
return actual . some ( function ( item ) {
173
- return deepCompare ( item , expected , comparator ) ;
182
+ return deepCompare ( item , expected , comparator , matchAgainstAnyProp ) ;
174
183
} ) ;
175
184
}
176
185
177
186
switch ( actualType ) {
178
187
case 'object' :
179
188
var key ;
180
- if ( keyWasDollar || ( expectedType !== 'object' ) ) {
189
+ if ( matchAgainstAnyProp ) {
181
190
for ( key in actual ) {
182
191
if ( ( key . charAt ( 0 ) !== '$' ) && deepCompare ( actual [ key ] , expected , comparator ) ) {
183
192
return true ;
184
193
}
185
194
}
186
195
return false ;
187
- } else {
196
+ } else if ( expectedType === 'object' ) {
188
197
for ( key in expected ) {
189
198
var expectedVal = expected [ key ] ;
190
199
if ( isFunction ( expectedVal ) ) {
@@ -198,13 +207,13 @@ function deepCompare(actual, expected, comparator, keyWasDollar) {
198
207
}
199
208
}
200
209
return true ;
210
+ } else {
211
+ return comparator ( actual , expected ) ;
201
212
}
202
213
break ;
214
+ case 'function' :
215
+ return false ;
203
216
default :
204
- if ( expectedType === 'object' ) {
205
- return false ;
206
- }
207
-
208
217
return comparator ( actual , expected ) ;
209
218
}
210
219
}
0 commit comments