In order to make sure my site works for a user I need to check that both JSON and XMLHttpRequest() are defined as objects by their browser. Rather than if/else I thought I'd use the ternary operator:

condition ? true : false.

I tried the following and it doesn't work correctly. Firstly, the following alerts "Success":

(typeof(JSON) && typeof(XMLHttpRequest()) == "object" ? window.alert("Success") : window.alert("Fail"));

...which is all good until I try:

(typeof(JSONsdsdsd) && typeof(XMLHttpRequest()) == "object" ? window.alert("Success") : window.alert("Fail"));

...which should have alerted "fail". I then try:

(typeof(JSON) && typeof(XMLHttpRequestghfh()) == "object" ? window.alert("Success") : window.alert("Fail"));

...which results in no alert box coming up.

I'd be grateful if someone with more experience could point out where I've gone wrong. Thanks in advance for any help/tips/pointers :)

Recommended Answers

All 4 Replies

JRW,

For undefined members, typeof returns "undefined" , which (somewhat confusingly) is not falsy!

The reason is that typeof always returns a string (including "undefined" ) and any string that is not empty is also not falsy. Empty strings are falsy.

In fact, typeof always unambiguously returns a string (unless its argument generates a javascript error). Therefore, regardless of whether member x exists or not, and regardless of type, (typeof x) ? true : false will always return true .

The test you want is actually simpler - just eliminate typeof to give if(x)..... . If x is a member (of any type) then the expresion will return true, and if x does not exist then the expresion will return false.

A couple of other things:

When testing whether a function/method exists, just use its name, x , without calling it, x() .

You must also protect a composite test (to the left of the ?) with brackets.

So try:

(JSONsdsdsd && XMLHttpRequest)  ? alert("Success") : alert("Fail");

The test should return false and trigger "Fail".

Airshow

JRW,

For undefined members, typeof returns "undefined" , which (somewhat confusingly) is not falsy!

The reason is that typeof always returns a string (including "undefined" ) and any string that is not empty is also not falsy. Empty strings are falsy.

In fact, typeof always unambiguously returns a string (unless its argument generates a javascript error). Therefore, regardless of whether member x exists or not, and regardless of type, (typeof x) ? true : false will always return true .

The test you want is actually simpler - just eliminate typeof to give if(x)..... . If x is a member (of any type) then the expresion will return true, and if x does not exist then the expresion will return false.

A couple of other things:

When testing whether a function/method exists, just use its name, x , without calling it, x() .

You must also protect a composite test (to the left of the ?) with brackets.

So try:

(JSONsdsdsd && XMLHttpRequest)  ? alert("Success") : alert("Fail");

The test should return false and trigger "Fail".

Airshow

Thanks airshow. The following works as expected:

(JSON && XMLHttpRequest) ? window.alert("Success") : window.alert("Fail");

but when I add some garbage characters neither success or fail is triggered:

(JSONotexist && XMLHttpRequestgarbage) ? window.alert("Success") : window.alert("Fail");

Can I assume this is a JavaScript error? When I explicitly define JSON or XMLHttpRequest as false:

var JSON = false;
(JSON && XMLHttpRequest) ? window.alert("Success") : window.alert("Fail");

the fail alert pops up.

Thanks,

jrw89

I was advising without testing before - always dangerous.
.....
<conducts tests>
.....
Sorry, for global variables to test whether a member exists/doesn't exits you can use the form window.xxx or window['xxx'] .

So try (window.JSONotexist && window.XMLHttpRequestgarbage) ? alert("Success") : alert("Fail"); In functions, it's quite common to see the tertiary operator used to apply a default value when formal parameters are missing, as follows:

function foo(x, y) {
	x = (!x) ? "default" : x;
	y = (!y) ? 0 : y;
	.....
}

You have to be a little careful because y=0 will pass the test (!y) in the same way as y-undefined. So whereas y = (!y) ? 0 : y; makes sense, y = (!y) ? -1 : y; would not make sense if you wanted to allow y=0 (it would end up as y=-1 the same as if the y parameter was not included).

In this case, you might choose to use y = (!y && y!==0) ? -1 : y; .

Airshow

I was advising without testing before - always dangerous.
.....
<conducts tests>
.....
Sorry, for global variables to test whether a member exists/doesn't exits you can use the form window.xxx or window['xxx'] .

So try (window.JSONotexist && window.XMLHttpRequestgarbage) ? alert("Success") : alert("Fail"); In functions, it's quite common to see the tertiary operator used to apply a default value when formal parameters are missing, as follows:

function foo(x, y) {
	x = (!x) ? "default" : x;
	y = (!y) ? 0 : y;
	.....
}

You have to be a little careful because y=0 will pass the test (!y) in the same way as y-undefined. So whereas y = (!y) ? 0 : y; makes sense, y = (!y) ? -1 : y; would not make sense if you wanted to allow y=0 (it would end up as y=-1 the same as if the y parameter was not included).

In this case, you might choose to use y = (!y && y!==0) ? -1 : y; .

Airshow

Thanks Airshow! It works brilliant and I've learned a lot more to apply to other aspects of my JavaScript programming.:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.