Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Four ways to judge JS data types


May 30, 2021 Article blog



In the ECMAScript specification, a total of seven data types are defined, divided into basic types and reference types, as follows:

Basic types: String, Number, Boolean, Symbol, Undefined, Null Reference Type: Object

The basic type, also known as a simple type, is a simple segment of data that, because it occupies a fixed space, is stored in the stack, i.e. accessed by value, in order to facilitate the speed of variable queries.

Reference types, also known as complex types, cannot be stored in a stack because the size of their values changes, otherwise they slow down variable queries, so their values are stored in the heap, and the values stored at the variables are pointers to the memory of the stored object, i.e. accessed on a per-site basis. In addition to Object, reference types include Function, Array, RegExp, Date, and so on.

Since ECMAScript is loosely typed, there is a need for a means of detecting the data type of a given variable. JavaScript also provides a variety of methods for this problem, but unfortunately the results from different approaches vary.

Here are four commonly used methods and a brief analysis of the problems with each method.

1、typeof

Typeof is an operator that follows a monary expression to the right and returns the data type of the expression. The results returned are expressed as strings of this type (all lowercase letters) and include the following 7 categories: number, boolean, symbol, string, object, undefined, function, and so on.

typeof';/string is valid

typeof1;/number is valid

typeofSymbol();/symbol is valid

typeoftrue;//boolean is valid

typeofundefined;//undefined is valid

typeofnull;/object is invalid

typeof.//object is not valid

typeofnewFunction();/function is valid

typeofnewDate(); //object is invalid

typeofnewRegExp(); //object is invalid

Sometimes the typeof operator returns some confusing but technically correct values:

  • For basic types, all but null can return the correct results.
  • For reference types, the object type is returned except function.
  • For null, returns the object type.
  • For function returns the function type.

Where null has its own data type Null, the array, date, and regular in the reference type all have their own specific types, and typeof for these types of processing, only returns the Object type at the top of its prototype chain, no error, but not the result we want.

2、instanceof

instanceof is an instance that determines whether A is B, the expression is: A instanceof B, and if A is an instance of B, returns true, otherwise false is returned. It is important to note here that instanceof detects a prototype, and we simulate its internal execution with a piece of pseudo-code:

instanceof (A,B) = {

varL = A.__proto__;

varR = B.prototype;

if(L === R) {

The internal property of A __proto__ prototype object that points to B

returntrue;

}

returnfalse;

}

As you can see from the above process, when A's proto points to B's prototype, it is considered an instance of B, and let's look at a few more examples:

[] instanceof Array;// true

{} instanceof Object;// true

newDate() instanceof Date;// true

function Person(){};

newPerson() instanceof Person;

[] instanceof Object;// true

newDate() instanceof Object;// true

newPerson instanceof Object;// true

We've found that while instanceof can tell that it's an instance of Array, it thinks it's also an instance of Object, so why?

Let's analyze the relationship between the three:

From the instanceof, it can be determined that the .proto points to Array.prototype, while Array.prototype.proto points to Object.prototype, and finally Object.prototype.proto points to null, marking the end of the prototype chain. As a result, a prototype chain has been formed within the company:

 Four ways to judge JS data types1

As you can see from the prototype chain, the proto of is directed directly to Array.prototype and indirectly to Object.prototype, so according to the judgment rules of instanceof, this is an example of Object. B y analogy, similar new Date() and new Person() form a corresponding prototype chain. Therefore, instanceof can only be used to determine whether two objects belong to an instance relationship, not what type an object instance belongs to.

The problem with the instanceof operator is that it assumes only one global execution environment. I f a Web page contains more than one framework, there are actually more than two different global execution environments, resulting in more than two different versions of the constructor. If you pass an array from one frame to another, the incoming array has different constructors than the array natively created in the second frame.

variframe = document.createElement('iframe');

document.body.appendChild(iframe);

xArray = window.frames[0]. Array;

vararr =newxArray(1,2,3);// [1,2,3]

arr instanceof Array;// false

if(Array.isArray(value)){

Do something with the array

}

Array.isArray() essentially detects the value of the object, which is an internal property of the object that contains the type information of the object in the format of "object Xxx", which is the specific type. For an array, the value of the value of the class is the value of the object Array.

3、constructor

When a function F is defined, the JS engine adds a prototype prototype to the F prototype, and then adds a constructor property to the prototype, which points to a reference to F. Here's what it looks like:

 Four ways to judge JS data types2

F is treated as a constructor when var f is new F(), f is an instance object of F, and the constructor on the F prototype is passed to f, so f.constructor is F

 Four ways to judge JS data types3

As you can see, F refers to itself using the constructor on the prototype object, and when F creates the object as a constructor, the constructor on the prototype is inherited to the newly created object, which is the type of the new object from the prototype chain point of view. The point is that new objects have traceable data types after they are born.

Similarly, built-in objects in JavaScript do this when built internally:

 Four ways to judge JS data types4

Details:

null and undefined are invalid objects, so there will be no constructor, and both types of data need to be judged in other ways. 2. The constructor of the function is unstable, which is mainly reflected in the custom object, when the developer rewrites the prototype, the original constructor reference is lost, and the constructor defaults to Object

 Four ways to judge JS data types5

Why object?

Because the prototype is re-assigned to a literal amount of the new Object(), the new Object() passes the constructor on the Object prototype to the object itself.

Therefore, in order to standardize development, it is generally necessary to re-assign the constructor when rewriting the object prototype to ensure that the type of the object instance is not tampered with.

4、toString

ToString() is the prototype method of Object, which is called and returns the current object by default. This is an internal property in the form of object Xxx, where Xxx is the type of object.

For object objects, calling toString() directly returns the object object. For other objects, calls are required to return the correct type information.

Object.prototype.toString.call('') ; [object String]

Object.prototype.toString.call(1) ; [object Number]

Object.prototype.toString.call(true) ;// [object Boolean]

Object.prototype.toString.call(Symbol());//[object Symbol]

Object.prototype.toString.call(undefined) ;// [object Undefined]

Object.prototype.toString.call(null) ;// [object Null]

Object.prototype.toString.call(newFunction()) ;// [object Function]

Object.prototype.toString.call(newDate()) ;// [object Date]

Object.prototype.toString.call([]) ;// [object Array]

Object.prototype.toString.call(newRegExp()) ;// [object RegExp]

Object.prototype.toString.call(newError()) ;// [object Error]

Object.prototype.toString.call(document) ;// [object HTMLDocument]

Object.prototype.toString.call (window);//object global window is a reference to the global object