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 work in both of the following cases:
Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(new Array()); // [object Array]
Great, no [object Object]
in sight! Sadly, this method still manages to fail with this:
var arr = Object.create(Array.prototype);
Object.prototype.toString.call(arr); // [object Object]
This is frustrating, so say the least. My arr
object has all the methods of an array, it functions like an array, and for all purposes, it is an array. Yet JavaScript doesn't provide the tools to identify it as such.
Is there any way to figure out if an object inherits from a particular prototype? I suppose you could iterate through the prototypes like so:
function inherits(obj, proto) {
while (obj != null) {
if (obj == proto) return true;
obj = Object.getPrototypeOf(obj);
}
return false;
}
inherits(Object.create(Array.prototype), Array.prototype); // true
But it feels a tad hacky. Is there any cleaner approach?
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With