No. There are some cases where obj instanceof Array can be false, even if obj is an Array.
You do have to be careful with instanceof in some edge cases, though, particularly if you're writing a library and so have less control / knowledge of the environment in which it will be running. The issue is that if you're working in a multiple-window environment (frames, iframes), you might receive a Date d (for instance) from another window, in which case d instanceof Date will be false — because d's prototype is the Date.prototype in the other window, not the Date.prototype in the window where your code is running. And in most cases you don't care, you just want to know whether it has all the Date stuff on it so you can use it.
Source: Nifty Snippets
This example, applies to array objects too and so on.
And the standard method suggest by ECMAScript standards to find the class of an Object is to use the toString method from Object.prototype and isArray(variable) uses it internally.
Between the constructors, the relationship or prototype chain is:
Array -> Function.prototype -> Object.prototype
Object -> Function.prototype -> Object.prototype
The 1st is true because a constructor is a Function and functions are themselves Objects.
Array instanceof Function // true
Object instanceof Function // true
(function () {}) instanceof Object // true
You're testing the Array constructor. The Array constructor is a function used for creating arrays. So Array instanceof Function is true, and Array instanceof Object is true (since all JS objects inherit from the Object prototype. But since this is a constructor function, not an actual array Array instanceof Array is false.
Object is the Object constructor, which all objects inherit from. Since its still a function Object instanceof Function is true, as is Object instanceof Object.
None of that is what you're really meaning (I think) to test. We can test an actual array (rather than the constructor)
and get [] instanceof Array and [] instanceof Object to be true (while [] instanceof Function is false). This is because all arrays are arrays, all arrays are objects, but arrays are not functions.
we can also test an object and get
{} instanceof Object is true, but {} instanceof Array and {} instanceof Function are false.
The key things here
Arrayis a reference to a constructor function, not an actual array. Constructor functions are Functions, and all Functions are Objects.An Actual Array is an Array, which means its an Object, but is not a Function.
Under the covers
instanceofis looking up an objects "prototype chain" to find any constructors that it inherits from.
1.What is the difference between these two solutions?
isArray is an ES5 method so not supported by older browsers, but it reliably determines if an object is an Array.
instanceof only checks if Array.prototype is on an object's [[Prototype]] chain. It fails when checking arrays across iframes since the Array constructor used for the instance will likely be different to the one used for the test.
2.Which of these two is the preferred solution?
"Preferred" assumes some criterion for selection. Generally, the preferred method is something like:
if (Object.prototype.toString.call(obj) == '[object Array]')
which suits ES3 browsers and works across iframes. If only ES5 browsers are in consideration, isArray is likely OK.
3.Which has a faster process time?
Largely irrelevant, since the processing time for both is negligible. Far more important to select the one that is reliable. An Array.isArray method can be added to browsers that don't have it built–in using:
if (!Array.isArray) {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
}
Difference between
Array.isArray(item)anditem instanceof ArrayAs Felix Kling mentioned in the comment,
instanceof Arraydoesn't work across iframes. To give you a specific example, try the following code:var iframeEl = document.createElement('iframe'); document.body.appendChild(iframeEl); iframeArray = window.frames[window.frames.length - 1].Array; var array1 = new Array(1,1,1,1); var array2 = new iframeArray(1,1,1,1); console.log(array1 instanceof Array); // true console.log(Array.isArray(array1)); // true console.log(array2 instanceof Array); // false console.log(Array.isArray(array2)); // trueAs you see in the example above, array created with the Array constructor in iframe (i.e.
array2) is not recognized as an array when you useinstanceof Array. However, it is correctly identified as an array when usingArray.isArray().If you are interested in knowing why
instanceof Arraydoesn't work across different globals (i.e.iframeorwindow), you can read more about it on here.Which of these two is the preferred solution?
In most cases
instanceof Arrayshould be enough. However, sinceinstanceof Arraydoesn't work correctly acrossiframes/window,Array.isArray()would be more robust solution.Make sure to check for browser compatibility though. If you need to support IE 8 or less,
Array.isArray()won't work (see Mozilla's doc).Which has a faster process time?
According to this jsperf,
instanceof Arrayis faster thanArray.isArray(). Which makes sense, becauseArray.isArray()performs more robust checking and therefore takes a slight performance hit.