1. The method of judging a real array
The easiest way to declare an array in javascript is:
var a = [];
The most direct way to determine whether it is an array is:
The code copy is as follows:
a instanceof Array //true
a.constructor == Array //true
Here comes an instanceof syntax. instanceof is a cloud operator. Like "+-*/", its syntax is as follows:
result = obj intanceof class
It is used to determine whether an object is an instance of a class, and the operation result returns true or false. The definition of class in JavaScript is initialized through a constructor, so the right operator of the instanceof syntax must be an instance of Function, that is, the class instanceof Function must be true, and if the right operator is not a Function when using instanceof, a TypeError exception will be thrown. All objects are instances of Object, so any object instanceof Object returns true. Although we say that objects are initialized through constructors, instanceof does not check whether the object is constructed by the function, but is inherited by the constructor's prototype. The following example can illustrate this problem:
The code copy is as follows:
function Range(low, high) {
this.low = low;
this.high = high;
}
Range.prototype.constructor == Range; //true
Range.prototype = {
include: function(x){ return (x >= this.low && x <= this.high); },
exclude: function(x){ return (x < this.low && x > this.high); }
}
var r = new Range(0, 100);
r instanceof Range; //false
r instanceof Object; //true
Range.prototype.constructor == Object; //true
Although r is constructed through new Range, r is not an instance of Range. This is the problem. The Range.prototype assignment statement overrides the default constructor. Before the prototype is assigned, the Range.prototype.constructor is Range, and after the assignment is made, it becomes an Object. This is easy to understand because
The code copy is as follows:
Range.prototype = {
include: function(x){ return (x >= this.low && x <= this.high); },
exclude: function(x){ return (x < this.low && x > this.high); }
}
Actually equivalent to:
The code copy is as follows:
Range.prototype = new Object({
include: function(x){ return (x >= this.low && x <= this.high); },
exclude: function(x){ return (x < this.low && x > this.high); }
});
So Range.prototype.constructor == Object, then the instance created through new Range is of course an instance of Object.
It's more direct to see the official explanation:
The instance of operator does not actually check whether r was initialized by the Range constructor. It checks whether it inherits from Range.prototype.
There is also a function typeof in JavaScript that has similar functions as instanceof, but it returns specific basic data types: number, string, function, object, undefined, boolean. There are only these six types, and those not within these six types return object, that is, typeof([]) returns object, not array.
Another syntax involved is constructor, constructor returns the constructor of the object:
The code copy is as follows:
var a = [];
a.constructor; //Array
The constructor is an object's initialization function, which uses new calls. If the object is an Array, then its constructor should be an Array, and the class you wrote is not necessarily true, because the constructor in the prototype may be changed.
2. Method of judging pseudo-array
There is a pseudo-array in JavaScript. It can be traversed using a traversal method similar to Array. It has a length attribute to get the length of the element. You can use the [] subscript to get the specified element. We call this kind of object a pseudo-array. The object in JQuery is a typical pseudo-array, as shown in the figure below:
Therefore, the key to judging whether it is a pseudo-array is to judge whether there is a length attribute and whether there is a basic array operation function splice. The following is the judgment method:
The code copy is as follows:
var is_array = function(value) {
return value &&
typeof value === 'object' &&
typeof value.length === 'number' &&
typeof value.splice === 'function' &&
!(value.propertyIsEnumerable('length'));
};
Here propertyIsEnumerable is used to determine whether the length property is enumerable. In fact, the native String object also has an Array effect, but we cannot treat it as an Array object, so we need to judge the typeof value == "object", because typeof a String object returns a string.