From: nick on
What's the "best" way to determine if a variable is defined?

I see a lot of code that looks like this:

// example 1
if (typeof x !== 'undefined') doStuff(x);

It won't throw an exception if you use it to operate on an undeclared
or deleted identifier.

If you're only testing declared variables, which seems like a
reasonable design decision, and are targeting only modern browsers you
could write this ():

// example 2
if (x !== undefined) doStuff(x);

Here's another way you could do it... I've rarely see it written like
this, but it gives the same result and should work in older browsers:

// example 3
if (x !== void 0) doStuff(x);

The third example is the most concise. The 'void' operator has been
around pretty much forever. I'm no js optimization expert, but I can't
imagine it being much less efficient than the first example.

The third example doesn't read as well as the second example, but (to
me) it's about as clear as the first, and with less room for error
(quoted string 'undefined' can be mistyped and not caught right away).

Is there any good reason not to use the 'void' operator to check
whether something is defined, assuming the author knows the variable
has been declared? Or is this another one of those things that has
been remembered and forgotten?

function isDefined (v) { return (v !== void 0) }
From: nick on

> could write this ():

I have no idea where those parentheses came from.
From: David Mark on
nick wrote:
> What's the "best" way to determine if a variable is defined?
>
> I see a lot of code that looks like this:
>
> // example 1
> if (typeof x !== 'undefined') doStuff(x);

You don't need to do a strict comparison there. The typeof operation
returns a string.

>
> It won't throw an exception if you use it to operate on an undeclared
> or deleted identifier.
>
> If you're only testing declared variables, which seems like a
> reasonable design decision, and are targeting only modern browsers you
> could write this ():
>
> // example 2
> if (x !== undefined) doStuff(x);

If x will be either be undefined or a "truthy" value (e.g. won't be
null), use boolean type conversion:-

if (x) {
doStuff(x);
}

That's something to think about at the design stage as well.

>
> Here's another way you could do it... I've rarely see it written like
> this, but it gives the same result and should work in older browsers:
>
> // example 3
> if (x !== void 0) doStuff(x);
>
> The third example is the most concise.

Do you mean the most compatible? AFAIK, it only beats #2 in that
category (and only in very ancient browsers).

> The 'void' operator has been
> around pretty much forever. I'm no js optimization expert, but I can't
> imagine it being much less efficient than the first example.

Neither can I.

>
> The third example doesn't read as well as the second example, but (to
> me) it's about as clear as the first, and with less room for error
> (quoted string 'undefined' can be mistyped and not caught right away).

It's less error-prone than the second for sure as the global - undefined
- value could be shadowed. As for mistyping 'undefined', that's a good
point. Don't do that. :) Perhaps use a macro? And if you will need
to make such comparisons often (and performance is not an issue), put
the test in a function.

>
> Is there any good reason not to use the 'void' operator to check
> whether something is defined, assuming the author knows the variable
> has been declared? Or is this another one of those things that has
> been remembered and forgotten?
>
> function isDefined (v) { return (v !== void 0) }

Not that I know of, but I find it to be less intuitive.
From: Bart Lateur on
David Mark wrote:

>If x will be either be undefined or a "truthy" value (e.g. won't be
>null), use boolean type conversion:-
>
>if (x) {
> doStuff(x);
>}

Carefull: x = 0 and x = "" both produce a false, too.

--
Bart Lateur
bart.lateur(a)telenet.be
From: David Mark on
Bart Lateur wrote:
> David Mark wrote:
>
>> If x will be either be undefined or a "truthy" value (e.g. won't be
>> null), use boolean type conversion:-
>>
>> if (x) {
>> doStuff(x);
>> }
>
> Carefull: x = 0 and x = "" both produce a false, too.
>

Example given; it wasn't meant to be a complete reference of "falsey"
values. And which did you leave out? :)