Reputation: 931
I've been using the same JavaScript library I've built for years, and now I'm encountering errors with this function:
IsArray : function ()
{
if (typeof arguments[0] == 'object')
{
var criterion = arguments[0].constructor.toString().match(/array/i);
return (criterion != null);
}
return false;
}
There are times when it is called when the following error is thrown:
TypeError: Cannot call method "toString" of undefined
I added the following prior to defining the criterion variable to remedy the issue:
if (arguments[0].constructor == null || arguments[0].constructor == undefined)
return false;
However, I'd like to understand how or why this would happen. I don't know why a variable that has a type of 'object' would not have a constructor. I've never seen it prior to this issue. And what bothers me about this is this all started a few weeks after I updated another library function that checks for nulls and empty strings to try to filter out empty arrays (when comparing an empty array to an empty string, it was returning a match).
Upvotes: 2
Views: 4950
Reputation: 8497
Well... As you may know, JavaScript is a bit surprising sometimes. With ES3, it was not easy at all to determine if an array was actually an array. So if you want to keep your legacy code, I think you should follow the great tips given by Douglas Crockford in JavaScript: The Good Parts.
JavaScript does not have a good mechanism for distinguishing between arrays and objects. We can work around that deficiency by defining our own is_array function:
var is_array = function (value) {
return value && typeof value === 'object' && value.constructor === Array;
};
Unfortunately, it fails to identify arrays that were constructed in a different window or frame. If we want to accurately detect those foreign arrays, we have to work a little harder:
var is_array = function (value) {
return Object.prototype.toString.apply(value) === '[object Array]';
};
Moreover, you should be very careful when you play with null
because Object.create(null)
creates an object without any prototype, typeof null
returns object and null == undefined
returns true...
With ES5, the best solution is to use Array.isArray()
.
Upvotes: 1
Reputation: 664538
Not all objects have a .constructor
property, e.g. Object.create(null)
, just like not all objects have a toString
method.
For your IsArray
function, you should use the native Array.isArray
method, or its usual polyfill.
Upvotes: 1