Data type classification

Basic data type: Number String Null Boolean Undefined Symbol Bigint Reference data type: Object

Note:functionarrayThey're not data types and broadly they're objects.NaNIt's not a data typetypeof NaN   // number  
NaN= = =NaN  // false
Copy the code

storage

Basic data type: Stored in the stack (stack). It occupies small space and has a fixed size. It is frequently used data, so it is stored in the stack. Reference data type: Stored in both stack and heap, occupying large space and variable size. The stack stores a pointer to the starting address of the entity in the heap.

The difference between

The assignment of the underlying data type opens up a new memory space, and the two values are completely independent of each other.

let a = 1;letB = a; b =2
console.log(a,b) / / 1. 2
Copy the code

The reference data type makes a copy of the address of the assigned object. They both point to objects in the same heap. When the value of one object changes, the value of the other changes. If one object is reassigned, the other object is not affected.

let a = {name:"jimmy"}
let b = a;
b.name = "chimmy";
console.log(a) // {name:"chimmy"}
b = {name:"jeck"}
console.log(a) // {name:"chimmy"}
console.log(b) // {name:"jeck"}
Copy the code
let a = {name:'jimmy'.age:22}
function change(obj){
 obj.age = 24;
 obj = {
   name:'chimmy'.age:21
 }
 return obj;
}
let b = change(a);
console.log(b.age); / / 21
console.log(a.age); / / 24
Copy the code

Obj = {name:’chimmy’, age:21} obj = {name:’chimmy’, age:21} obj = {name:’chimmy’, age:21} Insert {name:’chimmy’, age:21}, and return b as {name:’chimmy’, age:21}. {name:’ Jimmy ‘,age:24}

Note: for variables of reference type, == and === only determine whether the address of the reference is the same, not whether the specific properties and values of the object are the same. Therefore, return true if both variables point to the same object. So = = = {}, {} = = = [] [], [1, 2] = = = [1, 2] and {name: ‘Jimmy’} = = = {name: “Jimmy”} are false if you want to judge whether the object or an array of the two different really are the same, a simple method is to convert them to a string and then judge. Another approach is to recursively determine the value of each attribute until the type is basic, and then determine if it is the same.

Data type detection

typeof

Basic data types

typeof "string"     // string  
typeof 1            // number  
typeof undefined   // undefined  
typeof true        // boolean  
typeof Symbol(a)// symbol  
typeof null        // object 
Copy the code

For basic data types, typeof is null only. Reference data type

typeof {}           // 'object'
typeof []           // 'object'
typeof(() = > {})    // 'function'
Copy the code

The typeof operator determines the typeof an object and its subtypes, such as functions (callable objects), arrays (ordered indexed objects), and so on. Everything except the function returns the result of object. To sum up: Using Typeof to detect data types cannot accurately identify null array objects, etc., there are defects.

instanceof

The instanceof operator can be used to determine the type of the object. The principle is to test whether the prototype of the constructor appears on the prototype chain of the object being tested.

[] instanceof Array            // true
({}) instanceof Object         // true
(() = >{}) instanceof Function   // true
Copy the code

Instanceof can only accurately identify arrays and methods, but cannot accurately identify objects

let arr = [];
let fuc = () = > {};
arr instanceof Object // true
fuc instanceof Object // true
Copy the code

Array and Function are subtypes of Object, so the Object constructor is on the prototype chain of ARR and FUC. so

arr instanceof Object // true  
fuc instanceof Object // true
Copy the code

Object.prototype.toString

ToString () is the prototype method of Object, which returns a string in the format “[Object Xxx]”, where Xxx is the type of the Object. For Object objects, call toString() directly to return [Object Object]; Other objects need to be called by call to return the correct type information.

PS: Call because some data types do not have a toString method. Using call, you can change the reference to this. Equivalent to borrowed from the Object. The prototype. The toString method. For more information about call, please refer to my other article new, Call,apply,bind

Object.prototype.toString({})       // "[object Object]"
Object.prototype.toString.call({})  // Add "call" to the result
Object.prototype.toString.call(1)    // "[object Number]"
Object.prototype.toString.call('1')  // "[object String]"
Object.prototype.toString.call(true)  // "[object Boolean]"
Object.prototype.toString.call(function(){})  // "[object Function]"
Object.prototype.toString.call(null)   //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g)    //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([])       //"[object Array]"
Object.prototype.toString.call(document)  //"[object HTMLDocument]"
Object.prototype.toString.call(window)   //"[object Window]"
Copy the code

Object. The prototype. ToString. Call () can be accurately judged a data type, it can even make a distinction between the document and the window. Implement a general method to determine the data type

function getType(type){
  if(typeoftype ! = ="object") {return typeof type;
  }
  return Object.prototype.toString.call(type).slice(8, -1).toLowerCase();
}
Copy the code

Data type conversion

Cast

Convert to string

String()

String(null) // "null"
String(undefined) // "undefined"
String(true) // "true"
String([]) // " "
String([1.2]) / / 1, 2, ""
String({}) / / "[object object]"
String(function(){})/ / "function () {}"
Copy the code

Converted to digital

Number()

Transformation rules

  1. If Boolean, true and false are converted to 1 and 0, respectively;
  2. If it is a number, it returns itself;
  3. If null, return 0;
  4. If undefined, return NaN;
  5. If it is a string, follow the following rules: If the string contains only digits (or a hexadecimal string starting with 0X / 0X, allowing positive and negative signs), convert it to decimal. If the string contains a valid floating point format, convert it to a floating point number. If it is an empty string, convert it to 0. Return NaN if it is not a string in any of the above formats.

6. If Symbol is used, an error is thrown. 7. In the case of an object, call the object’s valueOf() method and convert the returned value according to the previous rule; If the result of the conversion is a NaN, the toString() method of the object is called, and the conversion returns the corresponding value again in the previous order.

The seventh simple rule can also be understood as this: the Number method returns NaN when it takes an object as an argument, unless it is an array with a single Number or an empty array.

The Number function converts a string to a Number and is much stricter than parseInt. Basically, as long as one character cannot be converted to a numeric value, the entire string is converted to NaN.

Number(true);        / / 1
Number(false);       / / 0
Number([]);          / / 0
Number({});          // NaN
Number('0111');      / / 111
Number(null);        / / 0
Number(' ');          / / 0
Number('1a');        // NaN
Number(-0X11);       / / - 17
Number('0X11')       / / 17
Copy the code

ParseInt () and parsefloat() first look at the character at position 0 to see if it is a significant digit; If not, the method returns NaN(not a number) and no further action is required. But if the character is a significant digit, the method looks at the character at position 1 and performs the same test. This process continues until a character that is not a significant number is found, and then the string of significant numbers preceding that character is converted to a number. The diagram below:

Convert to a Boolean value

Boolean() Is true except for undefined, null, false, “”, 0 (including +0, -0), and NaN converts to false.

Implicit type conversion

By logical operators (&&, | |,!) Operators (+, -, *, /), relational operators (>, <, <=, >=), equality operators (==), or if/while conditions occur when two data types are different.

!!!!!

Will be implicitly converted to Boolean for comparison

Implicit type conversion rules for ‘==’

  1. Rule 1: If one of the operators is null or undefined, then the other operator must be null or undefined to return true. Otherwise, both operators will return false
  2. Rule 2: If two operation values are of type String and number, the string is converted to number
  3. Rule 3: If an operation value is Boolean, convert to number
  4. Rule 4: Return false if one of them is of type Symbol;
  5. Rule 5: If an operation has an object value and the other is a string, number, or symbol, the object is converted to the original type (call the valueOf/toString method on object).
null= =undefined  // True Rule 1
null= =0  // False Rule 1
null= ="" // False Rule 1
'123'= =123   2 / / rules
""= =0 0= =false 1= =true // Both true // Rule 3
var a = {
  value: 0.valueOf: function() {
    this.value++;
    return this.value; }};// Note that a can be equal to 1, 2, 3 again
console.log(a == 1 && a == 2 && a ==3);  // True Object Implicitly converts rule 5
Copy the code

In actual development, use === instead of == to judge whether it is equal

Implicit type conversion rules for ‘+’

The ‘+’ operator can be used not only to add numbers but also to concatenate strings. Only if both sides of the ‘+’ sign are numbers, an addition operation is performed; If both sides are strings, concatenation is done without implicit type conversion.

  1. If one of them is a string and the other is undefined, NULL, or Boolean, the toString() method is called for string concatenation; If it is a pure object, an array, a regular, etc., then the default call object’s conversion method will have a priority, and then concatenation.
  2. If one of them is a number and the other is undefined, NULL, Boolean, or a number, it is converted to a number for addition
  3. If one is a string and the other is a number, concatenation is performed according to string rules.
1 + 2        // 3
'1' + '2'    // '12' normal case
// Let's look at the special case
'1' + undefined   // "1undefined" rule 1, undefined convert string
'1' + null        // "1NULL" rule 1, null conversion string
'1' + true        // "1true" rule 1, true converts strings
'1' + 1n          // '11' compares special string to BigInt, BigInt is converted to string
1 + undefined     // NaN rule 2, undefined converts numbers to add NaN
1 + null          // 1 Rule 2, null is converted to 0
1 + true          // 2 Rule 2: convert true to 1 and add them to 2
1 + 1n            // Error: cannot add BigInt and Number types directly
'1' + 3           Rule 3, string concatenation
Copy the code

Object conversion rules

First, the valueOf() method on the prototype chain is called, which returns if it has been converted to the base type, and then toString() is called again if it has not been converted to the base type. If it is not the base type yet, an error is thrown.

The following example overrides the valueOf and toString methods on an obj object

var obj = {
  value: 1.valueOf() {
    return 2;
  },
  toString() {
    return '3'}},console.log(obj + 1); 3 / / output
Copy the code

10 + {} // “10[object object]” {} = “10[object object]”; 10[object object]

Both valueOf and toString are methods on obJ object stereotypes. For more information on stereotypes, see my article JS Stereotype Chain

The Object constructor is described in detail as well as those methods. You can refer to my article Object

Test yourself to see if you have fully mastered the transformation rules

1.'123'= =123   // false or true?
2.' '= =null    // false or true?
3.' '= =0        // false or true?
4.[] = =0        // false or true?
5.[] = =' '       // false or true?
6.[] = =! []// false or true?
7.null= =undefined // false or true?
8.Number(null)     // Return what?
9.Number(' ')      // Return what?
10.parseInt(' ');    // Return what?
11.{} +10           // Return what?
Copy the code

Answer: 1 true 2 false 3 true 4 true 5 true 6 true 7 true 8 0 9 0 10 NaN 11 10

FAQ:

Why is []== 0,[]==”” true

When a side is found not to be of the original value type, the valueOf method is called first for the conversion

[].valueOf()  / / []
Copy the code

If you find that valueOf is not the original value type after the conversion, continue the conversion using the toString method

[].toString() / / ""
Copy the code

So []==”” is true

“” if == 0, we will continue to use Number for the conversion judgment

Number("") = =0 
Copy the code

So []==0 is true

Why [] ==! [] The result is true

According to operator precedence,! The priority is greater than ==, so it will be executed first! []! Convert a variable to a Boolean type. Null, undefined, NaN, and the empty string (” “) are all true, and the rest are false. [] ==! [] is equivalent to [] == false according to the implicit conversion rule for ‘==’. The third rule is based on the rule mentioned above (if an operand is a Boolean, it is converted to a numeric value before equality is compared — false converts to 0 and true converts to 1), [] ==! [] is equivalent to []== false is equivalent to []==0