Technical Article => Web => JavaScript

In JavaScript, there are two types of values: primitive and object. Primitives consist undefined, null, boolean, number and string. Other values such as array and function are objects. When applying + operation on different type of values, there would be three kinds of type conversion.

Primitive conversion Number conversion String conversion

There three type conversions have corresponding abstract operations in JavaScript: ToPrimitive(), ToNumber(), ToString().

For number addition, it's normal math addition(ToNumber). For strings, they are just string concatenations(ToString). For objects, it's a bit different because ToPrimitive doesn't know whether it's a number or string. Let's first take a look at below two expressions, what's the value of each expression?

({} + {})

({} + [])

When adding the objects, each object will be converted to its corresponding primitive value with ToPrimitive() and addition on the primitive values will be performed. The flow of addition would be:

Evaluate the left-hand side, and get the value. Evaluate the right-hand side, and get the value. Call ToPrimitive on both the left-hand and right-hand sides(No hint) If either primitive value is a String, skip to 7. Call ToNumber on both values. Return the sum of the values. Call ToString on both values. Return the concatenation of both values.

There are three hints: number, string and default. Normally if no hint is specified while doing the primitive conversion, number will be used as the hint. When the hint is number or default, it will try to call valueOf() first then toString() to get the primitive value. For a normal object(Except for Date, RegExp etc), the valueOf() will returns the object itself, hence the object is still not a primitive value, it will call toString() to get the primitive value. Hence an Object will finally call toString() to get the primitive value.

In above cases, {} will be converted to String which has value [object Object], an empty array will be converted to an empty string.

Hence the above two expressions have below results:

[object Object][object Object]

[object Object]

This behavior is different from other dynamic languages where + operation usually means merge. For example, in Ruby, if adding two arrays, it will return a new array which contains elements from both arrays.

irb(main):001:0> a = [1, 2] => [1, 2] irb(main):002:0> b = [3, 4] => [3, 4] irb(main):003:0> a + b => [1, 2, 3, 4]

While in JavaScript, the two arrays will be converted to strings first. Each element in each array will also be converted to string first and delimited by comma. The same expression above in Ruby will have below result in JavaScript.

a = [1, 2] (2) [1, 2] b = [3, 4] (2) [3, 4] a + b "1,23,4"

The purpose of this post is to emphasize that basics are really important to understand something. Even though you may know well about AngularJS, jQuery, React or VueJS, you may not be considered as a good front end developer if you don't have a good understanding of Vanilla JavaScript.