Skip to content Skip to sidebar Skip to footer

Checking For Undefined

I am utterly confused. I know this has been asked a million times. And I have looked at questions like: Test if something is not undefined in JavaScript Now the problem is when doi

Solution 1:

Short answer:

if (obj instanceofArray) {
    // obj is an array
}

Or, if you don't know whether obj is defined or not:

if ((typeof obj !== "undefined") && (obj instanceofArray)) {
    // obj is an array
}

To discuss why yours aren't quite right:

obj.anyProperty will throw a ReferenceError if obj is undefined. This affects all four of the things you put.

if (obj.length) will evaluate to false for an empty array, which isn't what you want. Because the length is 0 (a falsy value), it will falsely be inaccurate. This could also have issues if another object has a length property.

if (obj.length === undefined) will usually work, but it's frowned upon because undefined can be redefined. Someone could break your code by writing undefined = obj.length. This can also create false negatives; obj could happen to have a property called "length" and it would falsely call it an array.

if (typeof obj.length === "undefined") works fine, but could detect the same false negatives as the above.

if (obj.length == null) will work okay, but has the same bugs as above. In a double-equals (==), it matches null and undefined.

Solution 2:

I would do `

obj instanceofArray

to check if obj is an array

http://jsfiddle.net/Tcjk4/

Solution 3:

For what it's worth, here's how jQuery checks whether something is an array:

isArray: Array.isArray || function( obj ) {
    return jQuery.type(obj) === "array";
},

This uses ES5's Array.isArray if available, or a custom check in older browsers. jQuery makes this function accessible as $.isArray.

jQuery.type is basically an enhanced typeof that works around some limitations of the JavaScript language and browser bugs. Whereas typeof returns 'object' for anything object-like ({}, [], even null), $.type returns the internal JavaScript [[Class]] property of the object.

In fact, this method of determining type is actually safer than instanceof:

Both instanceof and constructor look very innocent and seem like great ways to check if an object is an array.

The problems arise when it comes to scripting in multi-frame DOM environments. In a nutshell, Array objects created within one iframe do not share [[Prototype]]s with arrays created within another iframe. Their constructors are different objects and so both instanceof and constructor checks fail:

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = newxArray(1,2,3); // [1,2,3]  // Boom!
arr instanceofArray; // false  // Boom!
arr.constructor === Array; // false

Solution 4:

More comment than answer.

While a test like object instanceof Array will work in most cases (it may fail where frames or inter–window communication are involved), it's a good idea to consider what you really need to test for and design the test accordingly. Testing explicitly whether an object is an array or not is almost always unnecessary.

In this case, it seems that you just want to use the length property for iterating over the object's numeric properties.

If that's the case, all you need to do is read the value of the length property and use it. Whether the property is missing, or hasn't been assigned a value, or has a value of undefined or 0, you don't want to do the loop. Fortunately, you can do all of those tests in one go (and also skip processing if the value is Null or '', which seems sensible too):

if (obj.length) {
  // iterate over numeric properties of obj
}

That will make the method generic, so it can be applied to any Object that has a suitable length property and some numeric properties (e.g. a jQuery object or an HTMLCollection object).

If you need some other feature of an array (say push or slice), you can also test for those.

If you are using the test as a logic fork (e.g. if it's an array do one thing, if it's a plain object do something else) then you should consider whether that's a sensible thing to do.

Solution 5:

var sizeArrayOrObject = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (typeof obj.key === 'undefined') size++;
    }
    return size;
};

sizeArrayOrObject([]);  // 0sizeArrayOrObject([5,6]);  // 2sizeArrayOrObject({});  // 0sizeArrayOrObject({id:8});  // 1

Post a Comment for "Checking For Undefined"