This article mainly talks about JS reference data types, wrapped objects, JS strong conversion, hidden data type conversion.

1. Reference data types

In ECMAScript, a reference type is a data structure that organizes data and functionality together.

In addition to objects, there are many more reference data types:

Array Array Date Date RegExp Regular Function FunctionCopy the code

In addition to the above data types, there are three more special (wrapper objects for basic data types) :

Packaging object

Boolean
Number
String
Copy the code

You may have encountered an interview question:

let num1 = 3
let num2 = new Number(3)
console.log(num === num2)  // false
Copy the code

The Number() object is the wrapper object for the Number of the primitive datatype:

typeof(num1) // number
typeof(num2) // object
Copy the code

These two are not the same thing, and of course they’re not equal, so let’s figure out, what does this wrapper object actually do?

let str = 'wanghuahua'
let str1 = str.substr(0, 4)
console.log(str1) // wang
console.log(String.substr) // undefined
Copy the code

STR is the basic data type. The substr method of String is undefined. This means that String does not have a substr method.

There is a computer operation in the middle, we call it the ‘processing plant’, so what operations are carried out in the processing plant? (key)

1, raw materials into the factory: the basic data type into the packaging object, because there is no method for the basic data type, if you want to operate the basic data type, it must be converted into the packaging object. Substr () {substr () {substr () {substr () {substr (); Wrapping objects toPrimitive data types the toPrimitive principle is provided in the ECMAScript specification, so this place will be converted according to toPrimitive.Copy the code

As mentioned in the previous article, this JS weakly typed language gives quite a lot of operations to the computer. This place is an obvious one. These operations are given to the computer, which increases the burden of the computer relatively.

The origin of the wrapper object, in fact, is not that complicated, is to handle the basic data type of data, add an intermediate layer.

ToPrimitive toPrimitive is what we often call js cast:

Second, JS cast

To cast is to convert manually:

ToString () converts toString() toString

let num2 = new String('hhh')
console.log(num2.toString()) // hhh
Copy the code

Each object has a toString() method, which is called automatically when the object is represented as a text value or when the object is referenced as a desired string.

Sometimes there are some really disgusting interview questions, but here are a few that aren’t common:

Console. log(null.tostring ()) // error console.log(undefined. ToString ()) // error console.log(true. ToString ()) // 'true' let a = 4 console.log(a.tostring ()) // 4 console.log(' HHH '.tostring ()) // 'HHH' console.log(Symbol().tostring ())) // Error reportedCopy the code

In addition, toString() takes a numeric argument to represent the base of the conversion:

Binary:.tostring (2); Octal:.tostring (8); Decimal:.tostring (10); Hexadecimal:.tostring (16);Copy the code

ValueOf () returns the original value

let num2 = new String('hhh')
console.log(num2.valueOf())  // hhh
Copy the code

JavaScript calls the valueOf() method to convert an object to a valueOf its primitive type (numeric, string, and Boolean). But we rarely need to call this function ourselves; valueOf methods are usually called automatically by JavaScript.

String => Return String Number => Return Number Date => Return timestamp Boolean => Return this value of Boolean Object => Return thisCopy the code

In addition to the above two methods, which are both methods of object, there are three operators:

(3) The Number operator tries to make the Number

Null converts to 0; undefined converts to NaN; true converts to 1; false converts to 0Copy the code

(4) All String operators are converted to strings

When we looked at toString, both null and undefined will give an error, but String does not. Everything is convertible, but the String operator cannot accept arguments.

String(null) // null
string(undefined) // undefined
Copy the code

Boolean operators all convert to true or false

Set Boolean to false and all the others to true.

Undefined null-0 0 or +0 NaN '' (empty string)Copy the code

Empty objects, empty arrays, and even this:

Boolean(new Boolean(false)) // true
Copy the code

(6) Convert ToPrimitive operator to original value

In addition to the above five methods, JS also has a relatively comprehensive ToPrimitive, which is not used for the underlying data types, only reference data types.

ToPrimitive(obj,type)
Copy the code

The ToPrimitive operator takes an object value to convert and an optional type value from which to convert:

The type string: Call obj's toString method first, if it is the original value, return, otherwise call obj's valueOf method in step 2, if it is the original value, return, otherwise raise TypeError in step 3: Call valueOf of obj first, return if it is the original value, otherwise call toString of obj in step 2, return if it is the original value, otherwise raise TypeError in step 3 if the type argument is null the object is Date, Type is set to String; otherwise, type is set to NumberCopy the code

Implicit data type conversion

Js is a type language, so the relative syntax is very loose. Strings can be operated with numbers, and numbers can also be operated with Bools. In the process of operation, implicit data type conversion is produced.

+ (string concatenation);
2, convert to number type:
++/--(increment and decrement operator) + - * / %(arithmetic operator) > < >= <= ==! = = = =! === (relational operator)Copy the code
3, meet! Boolean (logical non-operator), then type Boolean:

However, there are many common potholes, such as:

1, string concatenation + and arithmetic operator + are both +, which is it?

Common interview questions:  console.log(1 + 'true') // '1true' console.log(1 + true) // 2 console.log(1 + null) // 1 console.log(1 + undefined) // NaN console.log(null + undefined) //NaNCopy the code

The rule about string concatenation + and arithmetic operator + is that as long as one side is a string, the + is a string concatenation, and everything else is arithmetic operator.

Console. log(1 + 'true') // '1true' 'true' is a string, so it is a string concatenation. Log (1 + true) // 2 Number(1)+Number(true) 1+1 2 console.log(1 + null) // 1 Number(1)+Number(null) 1+0 1 console.log(1 + undefined) // Number(1)+Number(undefined) 0+undefined NaN console.log(null +undefined) //Number(null)+Number(undefined) 0+undefined: none of the sides of NaN is a string, so it is the operator. If it is the operator, then both sides will call the Number operatorCopy the code

2. Why 2<’10’,’2′>’10’?

Common interview questions: console.log(2>'10') // false console.log('2'>'10') // trueCopy the code
If one side of the relational operator is a string, the Number operator is called to convert the two sides to numbers and compare them
If both sides of the relational operator are strings, they are converted to numbers using the charCodeAt() method and then compared
console.log(2>'10') // Number(2)>Number(10) 2>10 false 
console.log('2'>'10') //2.charCodeAt()>10.charCodeAt() 50>49 true
Copy the code

‘2’>’10’ when charCodeAt() is performed, the first byte will be compared, if not, the result will be returned directly, if the first byte is the same, then the second byte will be compared. CharCodeAt () is first compared to charCodeAt().

3. Reference data types are implicitly converted to string first.

Console. log([1,2] == '1,2') //true in this procedure, if [1,2] is a reference data type, the valueOf() method will be called first. If it returns a reference data type, the toString() method will be calledCopy the code

4, logical non-operators and relational operators, why [] == 0! [] = = 0? (key)

Entry level:

console.log([] == 0) // true console.log(! [] == 0) // trueCopy the code

Why [] = 0,! [] is also equal to 0. Isn’t that destroying three views?

First, analyze [] == 0:
[].valueof ().toString() //" Both sides must convert to Number Number(") // 0 so trueCopy the code
Then analyze it! [] Why also 0:
Boolean operators are true except for undefined, null, -0, 0 or +0, NaN, and '' (empty string). Number(false) // 0 [] == 0 is also trueCopy the code

Don’t be in class

[] = =! [] //true [] == [] // falseCopy the code

[] is not true, [] is false?

[] = =! []
1, [] will still be converted to string, which is "" 2,! [] = false (); [] = false ()Copy the code
[] == [] (This is a pit)
We talked about this in the last article on stack memory. Reference data types are stored in the stack as addresses, so these two must be differentCopy the code

High class don’t

{} = =! {} // false {} == {} // falseCopy the code

{} and [] are both reference datatypes. Why is it false?

{} = =! {}
{} is still a string, but {} is a string "[object object]". 3, Number(""[object object]") and Number(falseCopy the code
{} = {}
Similarly, stack memory address is also compared, so falseCopy the code

On the js data type, the main is the implicit data type conversion, will often go wrong, this series of two articles is mainly to talk about the difference between JS assignment and assignment, strong conversion and implicit conversion we often appear problems.

Personal wechat official account: Little Jerry said that he usually sends some technical articles and reading notes, welcome to exchange.

Behind will continue to update some js based article, interested can point a concern.