tags:

views:

114

answers:

5

I had an interesting interview question today that stumped me a little. I was asked about falsey values. So undefined, NAn, Null, 0, an empty string all evaluate to false. What is the reason this is useful to know in javaScript? The only thing I can think of is instead of having to do this:

if(mystring === '' || mystring === undefined) { }

I can do this:

if(!mystring)

Is this the only useful application?

+2  A: 

It's useful to detect if a browser is has specific predefined objects:

if(!!navigator.geolocation){
  // executes if the browser has geolocation support
}

if(!!document.createElement('canvas').getContext){
  // executes if the browser supports <canvas>
}

Explanation: navigator.geolocation is an object or undefined. In the case it's an object !navigator.geolocation will return false, if it's undefined it'll return true. So, to check if a browser has geolocation enabled, you want to 'flip' the boolean once more, by adding another !.

Harmen
So if I did if(!navigator.geolocation){ } and it's undefined then this would return false?
elduderino
I don't get it... What's the difference between `if (!!foo.bar)` and `if (foo.bar)`?
Šime Vidas
@elduderino No, it would return true. The ! operator first converts its operand to a boolean value and then switches it... In the case ther navigator.geolocation is undefined, it will be converted to the boolean value false, and then switched to true...
Šime Vidas
@Šime Vidas: I've got these snippets from the Modernizr source. I think they use it too make absolutely sure they're dealing with a boolean. But I actually don't see a situation when there's difference between `if (!!foo.bar)` and `if (foo.bar)` neither...
Harmen
@Harmen I believe `!!` is not necessary since JavaScript has automatic type coercion. The expression in the header of if statements will automatically get converted to boolean, so you don't have to use `!!` do convert it explicitly to a boolean value...
Šime Vidas
@Šime Vidas - oh yeah of course it would. I also do not see the difference of using if (!!foo.bar) and if (foo.bar)
elduderino
In this case, there isn't any. The `!!` operators are used for typecasting into boolean, so if you want to explicitly convert a value to boolean, you use `!!value`.
Šime Vidas
Great, I understand this now, Thanks
elduderino
+2  A: 

It is important to know that 0 evaluates to false to prevent doing things like:

if(str.indexOf('foo'))
Felix Kling
ah yes, very good.
elduderino
+2  A: 

They're also useful for setting default values...

function foo(bar){
    alert(bar || "default");
}

I know a lot of people try to do

if (typeof(foo) === "undefined"){}

to get around falsiness, but that's got its own because problems

typeof(null) === "object"

for some reason

Mike Ruhlin
Yeah I knew that about null. Weird. Good examples. Thanks
elduderino
@elduderine a nastier thing about null is isNaN(null) === false.
Angiosperm
+3  A: 

It's important to understand how this works in JS, so you're not surprised. Not necessarily just what is falsey, but what is truthy and how they compare to each other.

One example is that '0' is considered equal to 0 with ==, but it is not equal to '' - though 0 is. JavaScript comparison isn't always transitive.

So this means that just because (foo==bar && bar==fizz) is true, (foo==fizz) is not always true. To go with the above example, '0'==0, and 0=='', but '0'!='' - because you're comparing strings in the latter instance, and they're not coerced to booleans.

Alex JL
+2  A: 

One dangerous issue of falsey values you have to be aware of is when checking the presence of a certain property.

Suppose you want to test for the availability of a new property; when this property can actually have a value of 0 or "", you can't simply check for its availability using

if (!someObject.someProperty)
    /* incorrectly assume that someProperty is unavailable */

In this case, you must check for it being really present or not:

if (typeof someObject.someProperty == "undefined")
    /* now it's really not available */

Also be aware that NaN isn't equal to anything, even not to itself (NaN != NaN).

Marcel Korpel
But you can legitimately set a property to undefined, thus breaking this test. It's almost certainly better to use someObject.hasOwnProperty, and to recursively check this if you actually care if the property exists anywhere in the objects prototype chain.
Angiosperm
@Angiosperm In JavaScript, object are dynamic anyway, so there is no practical difference between an object not having a property and an object having a property set to `undefined`
Šime Vidas
@Šime Vidas Scenario: our application calls out to some remote location to check the existence of a resource. The resource's existence is constant during the app's lifecycle. This checking can be expensive, so we want to start caching the call's result. Lets do that be setting some property of an object to the result of that call. The existing code simply checks if the result of the call is 'undefined' to decide if the resource exists. To not have to change our current interface, the cache mechanism would have to check if the appropriate property actually exists, rather than is just undefined.
Angiosperm
@Angiosperm: Please bare in mind that I'm checking the `typeof` a property, not its value.
Marcel Korpel
@Angiosperm In your scenario, I would set up the program to set `null` if the resource check returns `undefined`. Can you cite a relevant source that recommends `foo.hasOwnProperty` in favor of `typeof foo == "undefined"`?
Šime Vidas
@Šime Vidas I got nothin. @Marcel Korpel are there other values for which typeof returns "undefined"?
Angiosperm
@Angiosperm: Not that I know of, but I've just moved and can't look for it extensibly at the moment.
Marcel Korpel