...

View Full Version : Detecting the existence of a variable- discussion



WA
07-04-2002, 04:15 AM
This relates to using JavaScript to detect whether a variable (ie: x) exists. Now, I understand the "standard" way to do this is through the typeof method:

if (typeof(x)!="undefined") //if x exists

Now, in the past and in many of my scripts, I've resorted to simply using:

if (window.x)

instead to check for x's existence. As people had pointed out to me, this is unreliable in that should x be set to false (ie: x=0), window.x will also return false, even though x is actually defined.

My question/discussion is, are there times when window.x is suffice/appropriate to detect the existence of a variable, or is it essentially considered incorrect and obsolete? My position is, as long as you're sure of the kind of values x will be receiving, that it will not contain Boolean values, window.x is valid and enough to detect x's existence.

What are your thoughts?

jkd
07-04-2002, 05:28 AM
Big reason not to simply use:

if (window.variableName):

Javascript Strict Errors decrease performance. Read Alex's tutorial he submitted to your site ;).

typeof variableName

is the best way to check for variables. :)

Though, the idea of seeing if a variable exists seems kind of odd once you've ventured into some lower-level languages... I always get in the habit of declaring every variable explicitly that I might use in a function. Just makes the code clearer...

WA
07-04-2002, 06:08 AM
Though, the idea of seeing if a variable exists seems kind of odd once you've ventured into some lower-level languages... I always get in the habit of declaring every variable explicitly that I might use in a function.
There are cases I've found where you absolutely need to detect whether a variable exists, and cannot declare everything beforehand. For example, with the code:

var startit=setInterval("dothis()",1000)

Depending on how the above is called, if I need to stop it, using:

clearInterval(startit)

I absolutely must make sure first startit is defined:

if (typeof(startit)!="undefined")
clearInterval(startit)

brothercake
07-04-2002, 03:58 PM
Not necessarily - I've found that a simple

var startit;

startit = setInterval ...

amounts to the the same thing.

Although the strict method is theoretically better, it's not always practical. For example I had a script which need to go

if (something) {


But something changes a lot - sometimes its a boolean, sometimes and object, sometimes undefined and sometimes null. Being able to embrace them all with one statement is very useful indeed.

Also, minority browser throw a kink into the mix. for example:

if(typeof document.images["imagename"]!="undefined") {


works fine, to run the code only if that image exists except that in Konqueror 2, non existent images do not return undefined, they return null. So

if (document.images["imagename"])

is more reliable than the strict method.


I also wanna mention code size, eg:

if (typeof a!="undefined") {

is more characters than

if(a) {


In a large script with many hundreds of such expressions, the difference could mean +=5k to the script, or thereabouts. Sometimes a decrease in file size is more valuable than an increase in efficiency. In any case, the efficiency improvement is not noticeable in IE - only in Gecko can it be easily seen

mordred
07-04-2002, 04:55 PM
My opinion about checking for a variables existence are as follows: In most cases, I would stick to the "ordinary" method, means omitting the typeof check and simply test for the variable in an if-statement.

Reasons:

1.) typeof works in a manner that can be misleading. I mean that null is reported as "object". May result in cases where you have make an extra check for this special case, which results in more code you have to write and, IMHO, does not make the code more readable.

2.) As brothercake pointed out, sometimes less filesize is far more important than script efficiency - especially when you have a script that does not repeatedly check for existence of certain variables, objects etc. And isn't it mostly the case that a HTML document has a tiny javascript that's just doing some form validation or rollover image instead of a cutting-edge 3d-based first-person shooter coded in JS?

For me this typeof-strict-error is sort of the same advice not to include an array's length in the definition of a for loop. It surely improves performance, but often enough this improvement is in the nano-seconds, so who cares?
Also, why is Mozilla's JS engine devised in a way that typeof works better than the ordinary technique? There may be a valid reason to do so, I just want to know. Because for me in both of these two statements

if(typeof document.all != "undefined")
if (document.all)

the JS interpreter needs to somehow look up document, and then document.all. Or do I miss something?

Don't ge me wrong, there are certainly cased where typeof is definitely important for a script, but advising people to always do so seems to me like exaggerated evangelism. typeof is no sliver bullet; if a script behaves improperly or runs as fast as a slug, there's most certainly something wrong in the basic design of that application.

rawsweets
08-18-2002, 05:26 AM
Every custom entity (global or function) within the top-level of a document is available in the self/top object.

This example should give you a fair start...
/snip-----

for (var i in top) { .. loop through elements of top object...
if (i.toString() == 'variableName') alert('Your variable exists!'); // if element name matches... do what you like
}

-----snip/

FYI: You would need to search the element's value as a string to see if it's a function object. For example "if (top[i].toString().substring(0,9) == 'function ') ..." were true, then the entity is a function.

- rawsweets

mordred
08-18-2002, 06:23 AM
Your solution is totally unreliable.

Iterating through a window object won't get you members that are inenumerable. Plus, you can set the toString() method to return something very different than the ordinary case in the script. Furthermore, for strings it returns the strings value, not the variable name. Same for numbers. For dates, a specific date string is returned.

To sum it up: It doesn't work. Stay with typeof operators for a detailed object inspection or use the more common if-clause and test the outcome of a cast to boolean.

rawsweets
08-18-2002, 06:39 AM
Indeed, this only works in older versions of Netscape. Sorry for the misinformation folks!

UPDATE

Well it's certainly reliable (code is code), but it is not useful for cross-browser compatability (browsers aren't browsers)...

I ran the regular tests, and it seems that NS 4-6.x (Mac & PC), allows you to access (eg, check the name of) a custom JavaScript entity (global or function), via the "top/self" object. You can also parse the value to determine if it is a function object. However with NS 6, even built-in functions are listed in the top object, making it near impossible to discern which is a custom function.

I've used this method in the past, as a means of discovering what functions have been loaded, or to use a function's name in debugging efforts. It was quite useful, but I was living in a Netscape world...

IE does not support this "feature" of Netscape. Odd thing is, iCab (for Mac) does - and it's a standards champion (it's know for that). Then again, iCab may be emulating an older NS implementation (it's known for that too). Obviously this isn't a cross-platform method, but if the one for IE isn't either, at least you've got two!

beetle
08-18-2002, 07:03 AM
I find that it is not very often that I need to detect for a variable's existence, so I pretty much always use typeof if I need to make such a check.

WA, I do agree that it is acceptable to use window.x in cases where x will NEVER be boolean, becuase, afterall...a boolean value in x is the only sabot in that machine :D Were it not for that fact, would typeof even exist?

jkd
08-18-2002, 08:01 AM
Originally posted by beetle
WA, I do agree that it is acceptable to use window.x in cases where x will NEVER be boolean, becuase, afterall...a boolean value in x is the only sabot in that machine :D Were it not for that fact, would typeof even exist?

sabot? My dictionary says its a wooden shoe... (doesn't like seeing words he doesn't know).

Anyway, there are more cases than when x is a boolean that it won't work correctly:

empty strings ('', "", String()), 0, -0, null, Number.NaN, and undefined all convert to boolean false.

Also:

Boolean(new Boolean(false)) === true

Just some food for thought. :)

joh6nn
08-18-2002, 09:04 AM
wooden shoe?

i'm gonna paraphrase something i read out of a perl programming book:

"There is no wrong way to code Perl. Whatever gets the job done before your boss fires you, is the right way to do something".

i take this sort of approach to certain aspects of my programming. whatever gets the job done for me, in the given amount of time, in the least amount of code, is the right way to do something. if (x) { ... , if (typeof x ... , whatever; if it works, it works.

just my cent-and-a-half's worth.

beetle
08-18-2002, 10:07 AM
Hoboy. Ok, sabot. Didn't know you guys would miss that one.

I'm referring to the false (and better known) etymology of the word, 'Sabotage'. Read about it here (http://www.wordorigins.org/wordors.htm)

rawsweets
08-18-2002, 07:22 PM
I'm very curious about how to get the names of custom functions in IE. My current method only works in NS - it's in an earlier post here.

Should this be a new thread, or is this within scope?

dsvg
08-18-2002, 09:37 PM
...you're all wrong. The proper way to check for the existence of a property is:

'prop' in obj

;) For example:

if ('x' in window)

But then that doesn't work in NS4- so sticking to the typeof method is the only backwards compatible way. Come to think of it I don't know if 'in' works outside of the 'for' loop in any of the IE browsers below 5.5 (anyone got them that can test it?)

jkd: That works because any object - event a Boolean object with the value false - is equivalent to true when converted to a boolean value. It's a nice puzzle though. I have some even better ones regarding undefined but I can't remember them off the top of my head.

rawsweets
08-18-2002, 11:02 PM
This "If/in" control statement is new to me.

I just tried the following code in a test page...

/--------snip

x = new Array();
x['y'] = 5;
if ('y' in x) {
alert('good!');
}

---------snip/

Not good. Even keeping it simple, this thing didn't work in IE 4.5-5.15 or any of the older browsers NS browsers. Only works in iCab and Netscape 6+...

Oddly enough in IE and NS, when it didn't work, I got the same error message (citing NS debug report below).

/-----snip

missing ) after condition.
if ('e' in x) {
........^

------snip/

jkd
08-18-2002, 11:15 PM
Originally posted by dsvg
...you're all wrong. The proper way to check for the existence of a property is:

'prop' in obj

;)

Geez, why didn't I ever think of that? Genius - you really do learn something new everyday. :)

beetle
08-18-2002, 11:39 PM
I've only used 'in' for 'for' loops

joh6nn
08-18-2002, 11:59 PM
is that even valid?

jkd
08-19-2002, 12:00 AM
Originally posted by beetle
I've only used 'in' for 'for' loops

Most people do, it generally isn't a very widely publicized use of in outside of for loops.

http://devedge.netscape.com/library/manuals/2000/javascript/1.5/reference/ops.html#1066286

Has a bunch of examples I never a second thought about (until now of course). :(

jkd
08-19-2002, 12:04 AM
Originally posted by joh6nn
is that even valid?

Oh yeah, see that link I posted, and try it out for yourself. :)

dsvg
08-19-2002, 12:47 AM
rawsweets: That's a shame, it will be some time before it can be used then. Thanks for the info.

jkd: heh, I'm sure everyone is very happy to know that even you don't know everything about JavaScript. ;) I have to say that I'm not even close to being a genious however. My JavaScript is a bit rusty and there are a lot of areas I need to swat up before I will be up to your standard. :)

joh6nn: Sure, here is the algo from ECMAScript ED3. As you can see it makes no restrictions on the in operator being applicable only in the for loop:



11.8.7 The in operator

The production RelationalExpression : RelationalExpression in ShiftExpression is evaluated as follows:

1. Evaluate RelationalExpression.
2. Call GetValue(Result(1)).
3. Evaluate ShiftExpression.
4. Call GetValue(Result(3)).
5. If Result(4) is not an object, throw a TypeError exception.
6. Call ToString(Result(2)).
7. Call the [[HasProperty]] method of Result(4) with parameter Result(6).
8. Return Result(7).

beetle
08-19-2002, 06:57 PM
So could you then use that method to create global variables from within a function?

function blah() {
var x = 10;
var window.x = x;
}

???

dsvg
08-19-2002, 10:48 PM
Absolutely. :) I'm not sure if ns4 implements global variables as properties of the window object, but that is how all modern browsers implement global variables (and functions).



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum