Summary of several ways to determine object types in JavaScript

  • 2020-03-27 00:07:07
  • OfStack

As we know, the operators that detect object types in JavaScript are typeof, instanceof, and the constructor attribute of an object:

1) typeof operator typeof is a unary operator, and the returned result is a string that describes the typeof the operand. Example: "number", "string", "Boolean", "object", "function", "undefined". However, typeof is limited in its ability to return "object" for both Date and RegExp types. Such as:


typeof {}; // "object" 
typeof []; // "object" 
typeof new Date(); // "object" 

So it's only useful for distinguishing between objects and primitive types. To distinguish one object type from another, you must use other methods. For example, the instanceof operator or constructor genus of an object.

2) instanceof operator. The instanceof operator requires that the left operand be an object and the right operand be the name of the object class or constructor. The instanceof operator returns true if object is an instanceof a class or constructor. Returns false if object is not an instance of the specified class or function, or if object is null. Such as:


[] instanceof Array; // true 
[] instanceof Object; // true 
[] instanceof RegExp; // false 
new Date instanceof Date; // true 

Therefore, the instanceof operator can be used to determine whether the object is of array type:


function isArray(arr){ 
  return arr instanceof Array; 
} 

3) constructor attribute. In JavaScript, each object has a constructor attribute that references the constructor that initializes the object and is often used to determine the type of an unknown object. Given a known value, the typeof operator determines whether it is a primitive value or an object. If it is an object, you can use the constructor attribute to determine its type. So the function that determines the array can also be written like this:


function isArray(arr){ 
  return typeof arr == "object" && arr.constructor == Array; 
} 

In many cases, we can use the instanceof operator or the constructor attribute of the object to check whether the object is an array. For example, many JavaScript frameworks use these two methods to determine whether an object is an array type. But it fails to detect an array in a cross-frame page. The reason is that arrays created in different frames (iframes) do not share their prototype properties with each other. Such as:


<script>
window.onload=function(){
var iframe_arr=new window.frames[0].Array;
alert(iframe_arr instanceof Array); // false
alert(iframe_arr.constructor == Array); // false
}
</script>


Saw on the Ajaxian an accurate detection method, across the prototype chain call the toString () method: Object. The prototype. The toString (). The cross-frame problem above can be solved. When the Object. The prototype. ToString (o), will perform the following steps: 1) to obtain the class attribute of Object o. 2) connection string: "[object "+ result (1)+"]" 3) return result (2) for example:

Object. The prototype. ToString. Call ([]); // returns "[object Array]"
Object. The prototype. ToString. Call (/ reg/ig); // return "[object RegExp]"

In this way, we can write a robust function to determine whether an object is an array:


function isArray(arr){
  return Object.prototype.toString.call(arr) === "[object Array]";
}


This method has been recognized by many foreign javaScript masters, and will be used to detect arrays in jQuery 1.3. A maintainer of prototype.js writes the following function to get the type name of the object


/**
 * Returns internal [[Class]] property of an object
 *
 * Ecma-262, 15.2.4.2
 * Object.prototype.toString( )
 *
 * When the toString method is called, the following steps are taken: 
 * 1. Get the [[Class]] property of this object. 
 * 2. Compute a string value by concatenating the three strings "[object ", Result (1), and "]". 
 * 3. Return Result (2).
 *
 * __getClass(5); // => "Number"
 * __getClass({}); // => "Object"
 * __getClass(/foo/); // => "RegExp"
 * __getClass(''); // => "String"
 * __getClass(true); // => "Boolean"
 * __getClass([]); // => "Array"
 * __getClass(undefined); // => "Window"
 * __getClass(Element); // => "Constructor"
 *
 */
function __getClass(object){
  return Object.prototype.toString.call(object).match(/^[objects(.*)]$/)[1];
};


Extended to detect various object types:


var is ={
  types : ["Array", "Boolean", "Date", "Number", "Object", "RegExp", "String", "Window", "HTMLDocument"]
};
for(var i = 0, c; c = is.types[i ++ ]; ){
  is[c] = (function(type){
    return function(obj){
      return Object.prototype.toString.call(obj) == "[object " + type + "]";
    }
  )(c);
}
alert(is.Array([])); // true
alert(is.Date(new Date)); // true
alert(is.RegExp(/reg/ig)); // true



Related articles: