I would like advice as to best practice in testing object existence for cross-browser compatibility.
There seem to be many ways of testing for object/function/attribute existence. I could use jquery or another library, but for now I want to stick as closely as possible to w3c rather than use what amounts to a whole new language.
What I’m trying to do
I’m trying to write a utility library that tries to stick to w3c methods so I can just call
xAddEventListener(elem, type, listener, useCapture)
for all browsers rather than
elem.AddEventListener(type, listener, useCapture)
just for w3c compliant browsers. If another library already does this, please let me know.
I saw this today:
if (typeof node.addEventListener == "function")
but will this ever yield a different result than plain
if (node.addEventListener)
Style documents?
A reference to a standards or styles document would also be useful. I’ve found https://developer.mozilla.org/en/Browser_Detection_and_Cross_Browser_Support
but that was last updated in 2003. It advocates simple
if (document.images)
tests for most existence tests and
if (typeof(window.innerHeight) == 'number')
only with numbers because if(0) would evaluate to false
Examples to inspire comment:
if (myObject)
Can an object or function ever fail this simple test?
if (myObject != undefined)
When is this better than the previous test?
if (typeof(myObject) == 'object')
This appears to be the original way of calling type of, but some people say that typeof is a keyword and not a function. Also, why not one of the simpler tests?
if ( typeof myObject.function !== undefined ) {
One post said to alway use === or !== as it differentiates between null and undefined. Is this ever important in practice?
Another possibility is:
try {
node.addEventListener(...)
}
catch(err) {
node.attachEvent(...)
}
Which in python appears to be becoming the favourite way of dealing with these type of things.
Using exceptions looks potentially much cleaner as you could write easy to understand w3c compliant code, and then deal with exceptions when they come.
Anyway, what do people think? Please can you list the pros and cons of methods you like/dislike, rather than simply advocating your favourite.
It all depends on how specific you want to be / how much you want to assert before calling a function.
No, the only values that do not pass an
ifclause arefalse,0,"",NaN,undefinedandnull. These are all primitives. Objects (including functions) will always pass anifclause.If you want to check whether a value is "meaningful", i.e. not
undefinedornull. For example,will fail the
ifclause if the number is0, while you probably want0to be allowed. In such case,!= undefinedis a slightly better check.It is a keyword. You can call it in a function-like fashion, though. In its most bare form you can use
typeoflike this:You can, however, add (extraneous) parens since they don’t mean anything:
Just like you can do:
or even:
And you can then remove the space after the
typeofif you want, resulting in something that looks like a function call.As to why to use
typeof– you can be even more certain of the type of variable. With theif(...)test, the values that pass can be all kind of things – basically everything except the list I posted above. Withif(... != undefined), you allow even more to be passed. Withif(typeof ... == 'object'), you really only allow objects which might be necessary depending on what you’re processing.===is really preferred over==. While differentiating betweennullandundefinedis not always necessary, it is a very good practice to save yourself from the results of quirks like0 == ''. If you want to check whether a number is0, then=== 0is the way to go, since== 0also allows for an empty string (which you might not expect and probably don’t want). Even in cases==doesn’t cause quirks, you’d be better off using===at all times for consistency and avoiding surprising bugs.This is of course possible and very straight-forward. Note however that
try catchis said to be slow. Moreover, you don’t really account for why it fails. It’s a bit simple-minded (but may work fine).Yes, like I said above, the first only passes functions whilst the second allows anything except that list of "falsy" values. One could add
Node.addEventListener = 123, and it will pass theifclause in the second case. But IE fails to give a correcttypeofresult:I bet the same goes for
addEventListenerso you’d still be avoiding that function even if it exists.In the end, I would just use a simple
ifclause. Of course this will fail when you add weird things likeNode.addEventListener = 123, but then again you’re bound to expect weird things happen.