@@ -120,16 +120,20 @@ function filterFilter() {
120120 if ( ! isArray ( array ) ) return array ;
121121
122122 var predicateFn ;
123+ var matchAgainstAnyProp ;
123124
124125 switch ( typeof expression ) {
125126 case 'function' :
126127 predicateFn = expression ;
127128 break ;
128129 case 'boolean' :
129130 case 'number' :
130- case 'object' :
131131 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 ) ;
133137 break ;
134138 default :
135139 return array ;
@@ -140,51 +144,56 @@ function filterFilter() {
140144}
141145
142146// Helper functions for `filterFilter`
143- function createPredicateFn ( expression , comparator ) {
147+ function createPredicateFn ( expression , comparator , matchAgainstAnyProp ) {
144148 var predicateFn ;
145149
146150 if ( comparator === true ) {
147151 comparator = equals ;
148152 } else if ( ! isFunction ( comparator ) ) {
149153 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+
150159 actual = lowercase ( '' + actual ) ;
151160 expected = lowercase ( '' + expected ) ;
152161 return actual . indexOf ( expected ) !== - 1 ;
153162 } ;
154163 }
155164
156165 predicateFn = function ( item ) {
157- return deepCompare ( item , expression , comparator ) ;
166+ return deepCompare ( item , expression , comparator , matchAgainstAnyProp ) ;
158167 } ;
159168
160169 return predicateFn ;
161170}
162171
163- function deepCompare ( actual , expected , comparator , keyWasDollar ) {
172+ function deepCompare ( actual , expected , comparator , matchAgainstAnyProp ) {
164173 var actualType = typeof actual ;
165174 var expectedType = typeof expected ;
166175
167176 if ( ( expectedType === 'string' ) && ( expected . charAt ( 0 ) === '!' ) ) {
168- return ! deepCompare ( actual , expected . substring ( 1 ) , comparator ) ;
177+ return ! deepCompare ( actual , expected . substring ( 1 ) , comparator , matchAgainstAnyProp ) ;
169178 } else if ( actualType === 'array' ) {
170179 // 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`
172181 return actual . some ( function ( item ) {
173- return deepCompare ( item , expected , comparator ) ;
182+ return deepCompare ( item , expected , comparator , matchAgainstAnyProp ) ;
174183 } ) ;
175184 }
176185
177186 switch ( actualType ) {
178187 case 'object' :
179188 var key ;
180- if ( keyWasDollar || ( expectedType !== 'object' ) ) {
189+ if ( matchAgainstAnyProp ) {
181190 for ( key in actual ) {
182191 if ( ( key . charAt ( 0 ) !== '$' ) && deepCompare ( actual [ key ] , expected , comparator ) ) {
183192 return true ;
184193 }
185194 }
186195 return false ;
187- } else {
196+ } else if ( expectedType === 'object' ) {
188197 for ( key in expected ) {
189198 var expectedVal = expected [ key ] ;
190199 if ( isFunction ( expectedVal ) ) {
@@ -198,13 +207,13 @@ function deepCompare(actual, expected, comparator, keyWasDollar) {
198207 }
199208 }
200209 return true ;
210+ } else {
211+ return comparator ( actual , expected ) ;
201212 }
202213 break ;
214+ case 'function' :
215+ return false ;
203216 default :
204- if ( expectedType === 'object' ) {
205- return false ;
206- }
207-
208217 return comparator ( actual , expected ) ;
209218 }
210219}
0 commit comments