DEV Community

MOYED
MOYED

Posted on

4. Type Coercion

Articles


Definition

Type coercion is converting a value from one type to another.

Categorization

There are only 3 types of conversion in Javascript.

  • to string
  • to boolean
  • to number

Whether type coercion is intentioned by programmer or not, we can divide it into two type. Explicit type coercion which is also known as type casting, is when programmer intentionally alter the type of value. On the other hand, implicit type coercion is when Javascript automatically changes the type of value by given context.

Additionally, primitve value's type coercion and Object's type coercion works different.


Primitive type value

to string

Explicit

String(123); // '123'
Enter fullscreen mode Exit fullscreen mode

Symbol type can only be converted to string explicitly.

Implicit

+ binary operator (dont confuse with unary!) which one of operand is string converts non-string value to string type.

123 + 'hi1' // '123hi1'
Enter fullscreen mode Exit fullscreen mode

to Boolean

In Boolean, there are only 2 results; true or false.

Explicit

Boolean(2); //true
Enter fullscreen mode Exit fullscreen mode

List of falsy values

Boolean('');
Boolean(NaN);
Boolean(false);
Boolean(0);
Boolean(-0);
Boolean(null);
Boolean(undefined);
Enter fullscreen mode Exit fullscreen mode

Except this list, all values are converted to true.

Implicit

Logical operators(||,&&,!) implicitly converts to boolean type.

  • ! : flip the boolean value and return true or false
  • || : return first true value
console.log(2 || 1); // 2
Enter fullscreen mode Exit fullscreen mode
  • && : return first falty value, if none return the last value
console.log(0 && ""); // 0
console.log(2 && 1); // 1
Enter fullscreen mode Exit fullscreen mode

to Number

Explicit

Number('1'); // 1
Enter fullscreen mode Exit fullscreen mode

When converting string to number, Javascript engine trims the leading and trailing whitespaces. If trimmed string doesn't represent valid number, it returns NaN. If string is empty, return 0.

For null, it returns 0 and for undefined, it returns NaN.

Number('   2'); // 2
Number('   2 3'); // NaN
Number(''); // 0
Number(null); // 0
Number(undefined); // NaN
Enter fullscreen mode Exit fullscreen mode

Implicit

  • comparison operators(>, <..)

  • arithmetic operators(-,+, ..)
    For +, if one of operand is string type, then it converts to string type. + converts to numeric value, if both operands aren't string.

  • bitwise operators(|,&..)

  • unary + operator

  • loose equality operator ==
    We should be be careful with this operator. There's few exceptions.
    First, if both operand is string type, it doesn't triggers numeric conversion.
    Second case is with the null. null only loosely equals to null and undefined.
    Third case is with NaN. NaN is not loosely equals to itself.

console.log(null == 0); // false
console.log(null == null); // true
console.log(null == undefined); // true

console.log(NaN == NaN); // false
Enter fullscreen mode Exit fullscreen mode

Object type coercion

The logic itself is same. For object, still there are only 3 types of type conversion.
Algorithm works as follows.

  1. if input is primitve, just return it.

  2. Call input.toString() or input.valueOf().
    If operator does numeric conversion, do input.valueOf() first, and then do input.toString(). If operator does string conversion, do input.toString(), and then do input.valueOf(). Keep it mind, it returns true for any objects for boolean conversion.

  3. If both input.toString() and input.valueOf() doesn't returns primitve value, throw TypeError.

However, most objects(except wrapper object Number) doesn't have valueof or valueof returns this which is not primitve value. So we can just think that both conversion ends up calling toString.
Keep in mind,

console.log({}.toString()); // "[object Object]"
Enter fullscreen mode Exit fullscreen mode
console.log([1] / 2);
-> console.log('1' / 2);
-> console.log(1 / 2);

console.log('true' + {first: "second"});
-> console.log('true' + '[object Object]');

console.log(!+[0])
-> console.log(!0); // because + is unary operator
-> console.log(true);
Enter fullscreen mode Exit fullscreen mode

One thing, Date object's default is string converison. It means that

console.log(new Date(0) + 0 );
-> console.log('Thu Jan 01 1970 02:00:00 GMT+0200 (EET)' + 0);
-> console.log('Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0');

Enter fullscreen mode Exit fullscreen mode

Top comments (0)