Writing in the front

Today, let’s talk about the plus sign in JS, which is the little ‘+’. You might think that there are two cases of addition, numbers and strings. That’s what I thought at first, but it’s sweet… (The small plus sign solves a small problem with my recent project at the end of the article)

Often the more small knowledge point is more easily ignored. The smallest bits of knowledge test the basics. What is the result of {}+{}? What is the result of []+{}?

If you still know, spend ten minutes reading this article.

Js data type

There are two types of data in JS:

  • Primitive types: String, Number, Null, Boolean, Undefined, Symbol, Bigint
  • Reference type: Object (including array and function)

Note: There are 8 data types and 7 data types and object types in THE MDN document js. Bigint can represent integers with arbitrary precision. This article will not use it

Eight types of data portal: MDN document

The unary operation of addition

The internal operation of an additive unary operation

  • Syntax: + Expression
  • Note: In the unary operation of addition, Expression performs the Number(Expression) operation. Number is a method that converts parameters to numbers.

Results returned by different types of arguments

The practice test

Enter the following unary operators in the console and see their results

Results analysis

  • + ACE operation analysis:

Since ace is an undefined variable, it should be of undefined type, so Tonumber returns NaN.

  • +’ operation analysis:

The plus sign is followed by an empty string, which when converted to a number is 0, returns 0.

  • +false:

False is a Boolean value that is 0 when converted to a number.

  • +’123′ and +’ QQQ ‘

Both of these plus signs are strings; the former is a pure number and the latter is a character, so the first one can be converted to a number and the non-tree one to a NaN.

  • +{} and +[] :

Here the plus sign is followed by the object type, which is converted to the original value (the ToPrimitice method), which is then converted to the numeric type. The ToPrimitice method will be described in detail later.

ToPrimitive (input, PreferredType? Methods to introduce

ToPrimitice is an operation inside the JavaScript engine that converts the parameter input to its original value. There are four internal execution principles

  1. If the argument itself is the original value, return itself.

  2. If the ValueOf method is not called with an argument, the result returned by ValueOf returns the original value if it is the original value.

  3. If not, the toString method is called, and the result of the toString method is returned if it is the original value.

  4. If the result is not the original value, TypeError is thrown.

Tips1:

If you are not familiar with the valueOf and toString methods, refer to the NMD documentation for links. ValueOf method official documentation, plus a screenshot of toString method practice

Tips2:

The parameter PreferredType can be Number or String. ToPrimitive(input, PreferredType?) PreferredType is marked as String, then the order of the second and third steps of the conversion operation is reversed. If there is no PreferredType parameter, the value of the PreferredType is treated in four steps above the Number type.


Do you still remember the little practice case of unary operation?

+{} will go through the ToPrimitive method and convert to the original value before toNumber. The end result is NaN, so let’s take a look at the transformation process

// ToPrimitive({})

+ {}

Number({})

Number({}.valueOf());{}.valueof () isn't primitive

Number({}.toString())  // The result is a string, the original value

Number("[object Object]")//"[object object]" is a non-numeric character string

NaN

Copy the code

For the same reason, +[] is equally true

Number([])

Number([].toString())/ / [] the valueOf () isn 't my

Number(' ')

0

Copy the code

The binary operation of addition

internals

There is an addition operation that looks like this.

value1 + value2

When evaluating this expression, the internal steps look like this

Convert the two operands to their original values (the following is pseudocode for the mathematical representation, not JavaScript code that can be run): Prim1 := ToPrimitive(value1) Prim2 := ToPrimitive(value2) PreferredType is omitted, so the value of Date is String, and the value of other types is Number.

If either prim1 or prim2 is a string, the other is converted to a string and the result of the concatenation of the two strings is returned.

Otherwise, convert both prim1 and prim2 to numeric types and return their sum.

The practice test

Let’s take a look at the examples mentioned at the beginning of this article, {}+{}, []+[].

The result of {} + {}

For {}+{}, both sides of the plus sign are object types. First use ToPrimitive to convert them to a string type. To recall that the ToPrimitive method converts four procedures internally, toString should be called to convert them into two identical strings. The sum is still a string.

Let’s do a four-step analysis

//ToPrimitive({})

1.{} is a non-primitive value of the object type

2.The {}.valueof ()f method returns a non-original value

3.The {}.toString() method returns the string "[object object]"

4.Is a primitive value

Copy the code

So the result of {}+{} above is the addition of two “[object object]” strings. The concatenated string “[object object][object object]” is the final result.

The result of {} + []

{}+[] is the same as full, except that []. ToString returns a null character.


But be familiar with the toString and valueOf() methods. If you don’t know, look them up.

So the result of {}+[] is the string “[object object]”.

Some people may doubt the above analysis. I input these two binary operations into the terminal, and the printed result is the same as our analysis, with the result graph attached:

An interesting phenomenon

Careful friends may have a question when they see the screenshot above. The same? {}+[] = 0; {}+[] = 0; This is why, don’t worry, the following will slowly explain for you.

Why: {}+[] parses {} as an empty code block and ignores it. For example, if you write an arrow function ()=>{}, the contents inside the braces {} are code blocks.

The empty code block is ignored in {}+[] and becomes unary +[]. So this is 0. []+{} is the result of our previous analysis when we put arrays in front and objects in back. You can’t have {} at the beginning.

Development:

The {}.toString() method fails


This is the same as before, the js engine will consider the curly braces as a code block, so will report an error. Change it to ({}).toString().

At the end of the article

Refer to the article

  • JavaScript plus operator details
  • JS plus + operator details

Inspiration for the article

The inspiration for this article is currently working on a small project that has a data paging feature. The previous page is the current page minus 1, so the next page is the current page plus 1. But the error was reported.

Error: The current page number is retrieved from the URL address bar. The previous page is retrieved as a string. Subtraction of strings has implicit type conversions (converting to numbers); A string plus a number is still a string not a number

Fix the bug: Switch thinking so that the current page -0 is converted implicitly to a number and then increments by 1.

Through this little thing I just want to say that some very small things are often overlooked by everyone, and every knowledge has its meaning.

See the harvest

Hopefully, after reading this article, you learned the following:

  • ValueOf () and toString() methods
  • ToPrimitive (input, PreferredType? Principle of method
  • Unary addition of any data type
  • Binary addition of any data type

The most important is ToPrimitive(input, PreferredType?). If the input parameter is the original value, it will return the original value. If the input parameter is the original value, it will return the original value.

If it’s not the PreferredType or the toString method, the PreferredType is number or string. By default, the PreferredType is number, so valueOf is called first to see if the result is a raw value. If you don’t use the tosting method again to see if the result returned is the original value; If not, an error will be reported.

Finally, walk the heart of the article, I hope to be able to read carefully, if there is a wrong place welcome to comment area correction



See you next article…