Reputation: 8153
It may be that I'm just very groggy this morning, but I'm having trouble understanding why this returns as true
:
_.some([null, 0, 'yes', false]); // true
I know that _.some()
returns true if at least one of the elements passes the predicate test as true. But from my understanding, if no predicate is provided, _.identity()
is used. But console.log-ing each of those elements individually with _.identity()
didn't return true
for any of them. So why does it return true?
Upvotes: 0
Views: 134
Reputation: 2801
'yes'
is truthy:
_.some([null]) // false
_.some([0]) // false
_.some(['yes']) // true
_.some([false]) // false
From the Truth, equality in javascript link:
The construct if ( Expression ) Statement will coerce the result of evaluating the Expression to a boolean using the abstract method ToBoolean
for which the ES5 spec defines the following algorithm:
string
: The result is false if the argument is the empty String (its length is zero); otherwise the result is true.
Upvotes: 2
Reputation: 48277
Without a predicate, some
uses identity
, which uses the value itself, and 'yes'
is truthy.
A quick dive through the annotated source (paying special attention to cb
and the handling of missing predicates there) leaves you with, essentially, a coercion to boolean when they do:
if (predicate(obj[currentKey], currentKey, obj)) return true;
No predicate means you're working with the original value there, so if ('yes')
, which is true.
You're not seeing true
in the console for any of those values because _.identity
will return the value itself (so 'yes'
) rather than coercing it to a boolean. If you were to do !!'yes'
(coercion and double-not), you will see true
.
Upvotes: 2
Reputation: 664547
It doesn't need to return the literal value true
, it only needs to return a truthy value (although you always should return only booleans).
The non-empty string 'yes'
is truthy (you can test by Boolean('yes')
or !!'yes'
).
Upvotes: 1