As we all know, JavaScript can generally use typeof to judge the type of a data, except for some special cases, such as typeof null, which will output object. Here is another case. Using typeof to judge the array will also output object.
First create an array
let arr = [1,2,3] //Or let arr = new Array([1,2,3])
1.instanceof
console.log(arr instanceof Array) // true
2.Array.isArray()
console.log(Array.isArray(arr)) // true
3.Object.prototype.toString.call() (this is the key)
According to the description of MDN, each data type Object will have a toString() method. By default, this method will be inherited from the prototype of the Object object by each data type Object, and the array is also an Object. Naturally, this method will also be inherited. The following is the output of various types calling this function:
ar num = 123 num.toString() // '123' var str = 'hello' str.toString() // 'hello' var bool = false bool.toString() // 'false' var arr = [1, 2, 3] arr.toString() // '1,2,3' var obj = {lang:'zh'} obj.toString() // '[object Object]' var fn = function(){} fn.toString() // 'function(){}' null.toString() // Cannot read property 'toString' of null undefined.toString() // Cannot read property 'toString' of undefined
You can see that after calling toString() for numbers, strings, Booleans and arrays, the value will be converted to string type, while obj will return the object type. At this time, let's try to print the results of calling toString() for different types:
console.log(Object.toString()) // function Object() { [native code] } console.log(Array.toString()) // function Array() { [native code] } console.log(Number.toString()) // function Number() { [native code] } console.log(Boolean.toString()) // function Boolean() { [native code] } console.log(Function.toString()) // function Function() { [native code] } // ... the same applies to other types
It can be seen that although the toString() method of each data type inherits from the prototype of the Object object, it also overrides this method. The toString() method on the prototype of the Object object Object can output data types. Therefore, if you want to accurately judge the data type, you can directly use the toString() method on the prototype.
Use the call() method to take the Object whose data type you want to judge as a parameter (the principle is to change the Object's this point)
console.log(Object.prototype.toString.call(arr)) // [object Array]
Successful judgment.
PS: if you want to verify, you can delete toString() in Array, like this
// Define an array var arr = [1, 2, 3] // Does the array prototype have a toString() method console.log(Array.prototype.hasOwnProperty('toString')) //true // The array directly uses its own toString() method console.log(arr.toString()) // '1,2,3' console.log(arr.toString() === Object.prototype.toString.call(arr)) //false // The delete operator deletes toString() on the array prototype delete Array.prototype.toString // After deletion, does the array prototype still have a toString() method console.log(Array.prototype.hasOwnProperty('toString')) //false // When the deleted array uses toString() again, it will access this method to the upper layer, that is, toString() of Object console.log(arr.toString()) // '[object Array]' console.log(arr.toString() === Object.prototype.toString.call(arr)) //true
You can see that after deleting the toString() of the array type itself, calling toString() again will find the toString() in the Object() object prototype along the prototype chain, which can be used to judge the type.