Skip to main content
The JavaScript + operator functions as both a unary operator for numeric type conversion and a binary operator for numeric addition and string concatenation. Its execution behavior is strictly governed by ECMAScript’s implicit type coercion rules, specifically relying on the ToPrimitive, ToString, and ToNumeric internal abstract operations.

Unary Plus (+x)

The unary plus operator precedes a single operand. It evaluates the operand and applies the internal ToNumber operation.
If the operand is not already a Number, the JavaScript engine attempts to coerce it into one. It does not mutate the original variable; it returns a new evaluated value.
For objects, the engine first applies ToPrimitive(input, hint Number). It calls valueOf(), and if that does not return a primitive, it calls toString(), before finally applying ToNumber.

Binary Plus (x + y)

The binary plus operator requires two operands. It performs either string concatenation or numeric addition based on the types of the evaluated operands after primitive coercion.

The Evaluation Algorithm

When the engine encounters x + y, it executes the following sequence:
  1. Evaluate Operands: Both the left and right expressions are evaluated.
  2. ToPrimitive Conversion: The engine applies ToPrimitive(operand, default) to both values.
    • For most objects, the default hint behaves like the Number hint (invoking valueOf() then toString()).
    • Exception: Date objects treat the default hint as String (invoking toString() then valueOf()).
  3. String Check: If either of the resulting primitive values is a String, the engine applies ToString to both operands and performs string concatenation.
  4. Numeric Addition: If neither primitive is a String, the engine applies ToNumeric to both operands and performs mathematical addition.

Syntax Visualization: Numeric Addition

Triggered when neither resolved primitive is a String.

Syntax Visualization: String Concatenation

Triggered when at least one resolved primitive is a String.

Syntax Visualization: Object Coercion

Demonstrating the ToPrimitive step before the String/Numeric check.

Type-Specific Edge Cases

  • BigInt: The binary + operator supports BigInt operands, but mixing BigInt and Number throws a TypeError because the specification explicitly forbids implicit coercion between these two numeric types to prevent precision loss.
10n + 5n // 15n 10n + 5 // TypeError: Cannot mix BigInt and other types
Tired of Poor JavaScript Skills? Fix That With Deep Grasping!Learn More