Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

We believe that the basic data type of JS is the first thing that every front-end ER comes into contact with. When we memorize the 5 primitive types of Undefined, Null, Boolean, Number, String and reference type object, do we understand the difference between ES6 and TS data type and JS? What’s the difference between a primitive type and a reference type? How do you check what type a variable is? How many tests do you know?

Today we are going to answer those questions one by one.

1. What are the data types?

JS has 5 primitive types and 1 reference type, Undefined, Null, Boolean, Number and String. The reference type is Object. The contents are sorted as follows:

Since there are primitive types and reference types, what is the difference between the two types? How do you detect so many types?

2. What is the difference between primitive and reference types?

From the storage structure, the original data type is stack storage in memory, and the reference type is stack storage + heap storage. The difference is to pay attention to the deep copy or shallow copy when copying.

(1) Primitive type: stack storage

Its stored procedure looks like this

The value of the first variable is not affected when the value of the second variable is changed. For example:

var a = 10
var b = a
b = 20
console.log(a)  / / 10
Copy the code

(2) Reference type: stack storage + heap storage

The stored procedure for this is that all the reference type stores in the stack store is a reference, which is a reference address that points to an area of heap memory where the actual data is stored.

When a reference type is assigned to =, it is a shallow copy, which copies only the address of the reference in the stack. Both reference variables refer to the same memory area of the stack, so changing the value of the second variable affects the value of the first variable, for example:

var obj1 = new Object(a);var obj2 = obj1;
obj2.name = "I have a name.";
console.log(obj1.name); // I have a name
Copy the code

3. There are several ways to detect data types

Said the answer, I have a total of 4 kinds of typeof, Object. The prototype. ToString. Call (), the instance of and constructor

(1) the typeof

Typeof returns number, string, Boolean, undefined, object, function (all lowercase);

Here’s an example:

console.log(typeof ""); //string
console.log(typeof 1); // number
console.log(typeof true); // boolean
console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log(typeof []); // object
console.log(typeof function(){}); // function
console.log(typeof {}); // object
Copy the code

Typeof defects: null, [], {}, re, date, these detection results are all object, we can not further accurately determine what type. If you want to accurately detect the several types, we need to use the Object. The prototype. ToString. Call ()

(2) the Object. The prototype. ToString. Call ()

For the Object. The prototype. ToString. Call () method, which returns a form such as the string ‘[Object] XXX’. (XXX begins with capital letters), for example:

console.log(Object.prototype.toString.call("") = = ='[object String]'); // true
console.log(Object.prototype.toString.call(1) = = ='[object Number]'); // true
console.log(Object.prototype.toString.call(true) = = ='[object Boolean]'); // true
console.log(Object.prototype.toString.call(null) = = ='[object Null]'); // true
console.log(Object.prototype.toString.call(undefined) = = ='[object Undefined]'); // true
console.log(Object.prototype.toString.call([]) === '[object Array]'); // true
console.log(Object.prototype.toString.call({}) === '[object Object]'); // true
console.log(Object.prototype.toString.call(/[hbc]at/gi) = = ='[object RegExp]'); // true
Copy the code

There are dates and functions

// Date type
var date = new Date(a);console.log(Object.prototype.toString.call(date) === '[object Date]'); // true

// Function type
Function fn(){
  console.log (" test "); }console.log(Object.prototype.toString.call(fn) === '[object Function]'); // true
Copy the code

Here, it seems that the Object. The prototype. ToString. Call () has already covered most types of testing, functionality is very powerful, but there is a scene is powerless, is through the custom constructors instantiate the Object.

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Person("Rose".18);
console.log(Object.prototype.toString.call(person)); // "[object Object]"
Copy the code

Obviously, it can only detect an object, but not that person is an instanceof person, hence the third method instanceof.

(3) instanceof

Instanceof is used to check whether the constructor’s Prototype property appears on the prototype chain of an instance object.

Or above the chestnut, we modified, can solve the Object. The prototype. ToString. Call pain points () :

function Person(name, age) {
    this.name = name;
    this.age = age;
}
var person = new Person("Rose".18);
console.log(person instanceof Person); // true
Copy the code

While Instanceof addresses the pain point of custom constructor instantiation object detection, it falls short on some basic types of detection:

console.log("1" instanceof String); // false
console.log(1 instanceof Number); // false
console.log(true instanceof Boolean); // false
console.log(new String("1") instanceof String); //true 
console.log(new Number(1) instanceof Number); //true
console.log(new Boolean(false) instanceof Boolean); //true
console.log([] instanceof Array); //true
console.log(function(){} instanceof Function); //true
console.log({} instanceof Object); //true
Copy the code

As you can see, the normal primitive data type instanceof is not properly detected, only if the primitive types string, number, and Boolean are instantiated objects created by the new keyword. In addition, reference types like [], {}, and function are properly checked by instanceof.

However, null and undefined in the primitive type are not detected and will directly report an error. Because instanceof is used to check if the constructor’s Prototype property appears on the prototype chain of an instance object. Null and Undefined are themselves non-instantiable objects, so an error will be reported.

(4) constructor

The constructor property of the object instantiated by the constructor points to the constructor, which can also be used for type detection

// The detection principle
function Fn(){}; 
var f=new Fn(); 
console.log(f.constructor===Fn); // true
Copy the code

Let’s examine all the data types:

console.log(("1").constructor === String); // true
console.log((1).constructor === Number); // true
console.log((true).constructor === Boolean); // true
console.log(([]).constructor === Array); // true
console.log((function() {}).constructor === Function); // true
console.log(({}).constructor === Object); // true
console.log((null).constructor === Null); TypeError: Cannot read properties of null (reading 'constructor') TypeError: Cannot read properties of null (reading 'constructor')
console.log((undefined).constructor === Undefined); TypeError: Cannot read properties of undefined (reading 'constructor') TypeError: Cannot read properties of undefined (reading 'constructor')
Copy the code

In general, constructor’s detection is similar to instanceof’s, neither of which can detect null and undefined. All other data types are correctly detected.

(5) Summary

No single detection method can accurately detect all types, so we need to use the corresponding detection methods in different scenarios. I have compiled a list, which can be liked and bookmarked, and can be used as a self-check list at work:

Original article, hope to help you, but also for the community to contribute their own strength! If you like, please click “like”, “favorites” and “follow”

Akiko: A little dream in the front

Home page: To learn more, click on your home page