Identifying which objects are which is complicated in JavaScript, and figuring out which objects are arrays has something of a hacky solution. Fortunately, it manages to wor
ECMAScript 5 has introduced Array.isArray()
into javascript which provides a reliable way to check. For older browsers, we fix that by (quoted from this book)
function isArray(value) {
if (typeof Array.isArray === "function") {
return Array.isArray(value);
} else {
return Object.prototype.toString.call(value) === "[object Array]";
}
}
But i just found out the built-in function Array.isArray
does not work correctly when we use Object.create
(tested in chrome). I came up with a method that works:
function isArray(value) {
if (typeof value === "undefined" || value === null) {
return false;
}
do {
if (Object.prototype.toString.call(value) === "[object Array]") {
return true;
}
value= Object.getPrototypeOf(value);
} while (value);
return false;
}
Use it:
var arr = Object.create(Array.prototype);
var arr1 = Object.create(Object.create(Array.prototype));
var arr2 = new Array();
var arr3 = [];
isArray(arr);
isArray(arr1);
isArray(arr2);
isArray(arr3);
How about an instanceof operator? It returns true
for all your cases:
[] instanceof Array //true
new Array() instanceof Array //true
Object.create(Array.prototype) instanceof Array //true
However:
Object.create(Array.prototype) instanceof Object //also true
So be careful.
How about checking the constructor?
function inherits(obj, proto) {
return obj.constructor === proto.constructor;
}
inherits(Object.create(Array.prototype), Array.prototype); // true
it functions like an array, and for all purposes, it is an array
No. It has no auto-updating length
property. See this article why it's quite impossible to subclass Array
.
Is there any way to figure out if an object inherits from a particular prototype? I suppose you could iterate through the prototypes, but it feels a tad hacky.
That's just how to do it. A cleaner approach than a self-written function would be to use the instanceof operator:
arr instanceof Array; // true
See http://perfectionkills.com/how-ecmascript-5-still-does-not-allow-to-subclass-an-array/ for the definitive exposition of the problems in inheriting from Array.
Anyway, in the simplest case, where you are doing
var sort_of_an_array = Object.create(Array.prototype);
you can check using isPrototypeOf
:
Array.prototype.isPrototypeOf(sort_of_an_array)
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf.