views:

282

answers:

4

I've seen a couple web pages say that "a = b || 'blah'" should assign 'blah' to a if b is undefined or null. But if I type that into Firebug or use it in code, it complains that b is not defined, at list on FF3/win. Any hints?

Edit: I'm looking for the case where b may not exist at all. For example, a DOM node without an id.

+5  A: 

If b existed, and was false, null, etc, then it works in the way that you would expect. All you'll need to do is on the line above that, put var b = null;

This makes sense if you think about it. It basically does something like this...

a = function(){ if(b){return b;} else{ return 'blah' } }();

Note it is checking that the value of b is truthy... if b doesn't exist, you get an exception.

Regarding Undefined variables

"Undefined" in javascript doesn't mean 'variable doesn't exist'. It means "the value of the variable is the special value of undefined". Example:

alert(nosuchvariable);
=> throws exception

var somevariable; // note it's never assigned
alert(somevariable);
=> This alerts with 'undefined'

Regarding Checking if variables exist.

So if we try to read b and there is no such variable as b, we get an exception. If we're trying to find out if b is defined, then this isn't helpful.

You can see if global variables exist by checking the top-level window object. All global variables are actually just fields in the window object. Example:

foo = 'Hello';
alert( window.foo );
=> alerts 'Hello'

Because you know the window object already exists, you can check it's fields.
Checking for fields that don't exist in javascript will give you undefined and won't crash, so you can then do the coalesce, or put the undefined in a variable or whatever

For local variables (things declared with var), you can't check for their existence. they don't "live" anywhere in the way that global variables "live" in the window object, and any normal attempt to reference one will cause an exception: eg:

alert(a);
=> exception because a is meaningless
alert(d45pwiu4309m9rv43);
=> exception because that is equally meaningless

There is however one exception (that I know of, thanks J c in the comments), the typeof operator. If you try and get the type of something that doesn't exist, it won't crash, it will return the string "undefined".
This gives you a way of checking for non-existent local variables. eg:

if( typeof(djfsd) === "undefined" )
  alert('no such variable');

Regarding DOM elements that don't exist

There have been several comments mentioning DOM elements without ID's and so forth...

The fact that it's a DOM element isn't really relevant. Think of the DOM as a database or a file, and an element as a row in that database or word in that file. In order to do anything with it, you have to go searching through the database, find the right row, and pull it's data out. The data gets put into a javascript object. You then access it by manipulating that object, and maybe putting the object in a variable if you like. Example:

document.getElementById('foo');

this goes into the dom and looks for an element with an ID of 'foo'. If it finds one, it puts some information about that element into a javascript object, and then hands that object back to you. If it can't find the element, it will hand you back null, but all the normal rules still apply (you can stick the null in a variable, or whatever).

It doesn't affect the coalesce at all.

Orion Edwards
var b = null defeats the purpose...but your PS was helpful, so +1, but it doesn't solve the problem per se.
Kev
When you say you can't check for the existence of a local var, have you considered (typeof b === "undefined") as a test?
J c
A: 

|| is the short-circuited logical OR operator in Javascript, much like it is in C, C++, Java, C#, Perl, PHP, etc...

According to Wikipedia, if you put parentheses around b, it will work as you expect.

var a = (b) || 'blah';
R. Bemrose
This produces the same result for me, unfortunately. As I learned below, 'not defined' and 'undefined' are apparently different...
Kev
Hmm, true... the Wikipedia example is dealing with a property of an existing object which Javascript may handle differently. The whole idea of Orion Edwards's about declaring b beforehand isn't a bad one, though.
R. Bemrose
Except that if b exists, I've railroaded it.
Kev
Actually, || is not really the same as in C, C++, etc, since it doesn't return a boolean value, which lets it be used as a "default" operator. Additionally, I don't think grouping b like that does anything special, but I could be wrong.
J c
A: 

But if I type that into Firebug or use it in code, it complains that b is not defined, at list on FF3/win

What do you mean, "is not defined"? You mean Javascript doesn't know the variable? Then you may use window.b as "window" is the top level object, or first declare b with var b;; but only if it is a variable.

If it is a DOM element, you may have to try to hunt it down first, for example with document.getElementById:

a = document.getElementById('b') || 'blah'

works for me.

bart
>>> var bob = (hello) || 'yeah'ReferenceError: hello is not defined
Kev
Your phrase 'only if it is a variable' is key, please see the edit I made to the question. How do you coalesce if it isn't already a variable?
Kev
+3  A: 

I think you're looking for this:

var a = typeof b == 'undefined' ? 'blah' : b;
That's pretty much what came to my mind... assuming an actual variable instead of a string literal would result in: var a = typeof b == 'undefined' ? c : (b || c);
J c
This is a bit ugly but is the only working answer, I think.
Kev