Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The decrement (--) operator is a unary operator that subtracts exactly one from its operand and updates the operand’s value in place. It requires a mutable lvalue (such as a let variable, object property, or array element) to operate. Attempting to use it on an unassignable literal value results in a SyntaxError, while attempting to decrement a constant variable (e.g., a const declaration) throws a TypeError.

Syntax and Evaluation Strategy

The operator can be applied in two positions relative to the operand, which dictates its evaluation return value. In both cases, the operator implicitly coerces the operand to a numeric type before evaluation.
// Prefix syntax
--operand;

// Postfix syntax
operand--;
  • Prefix Decrement (--x): The operator coerces the operand to a numeric value, subtracts one, updates the reference, and evaluates to the new (decremented) value.
  • Postfix Decrement (x--): The operator coerces the operand to a numeric value, evaluates to the coerced numeric version of the original value, and then subtracts one and updates the reference. It does not evaluate to the exact original type if coercion occurred.
let prefixVar = "10";
let prefixResult = --prefixVar; 
// prefixVar is the Number 9, prefixResult is the Number 9

let postfixVar = "10";
let postfixResult = postfixVar--; 
// postfixVar is the Number 9, postfixResult is the Number 10 (not the String "10")

const constantVar = 5;
constantVar--; 
// Throws TypeError: Assignment to constant variable.

Automatic Semicolon Insertion (ASI) Restriction

When using the postfix decrement operator, JavaScript syntax strictly forbids a line terminator between the operand and the operator. If a line break is present, Automatic Semicolon Insertion (ASI) will terminate the statement after the operand. The parser then treats the subsequent -- as a prefix decrement operator for the next statement. If no valid operand follows it, this results in a SyntaxError.
let x = 5;
x
--; 
// Parsed as: x; --; 
// Throws SyntaxError: Unexpected token ';' (or Unexpected end of input)
// The engine treats '--' as a prefix operator, which fails because it lacks an operand.

Type Coercion and the ToNumeric Abstract Operation

If the operand is not already a numeric type, the -- operator implicitly invokes the internal ECMAScript ToNumeric abstract operation before performing the subtraction. This mutates both the value and the type of the operand.
let bool = false;
--bool; 
// bool is strictly the Number -1 (false coerces to 0, then decrements)

let empty = null;
empty--; 
// empty is strictly the Number -1 (null coerces to 0, then decrements)
The ToNumeric operation handles invalid numeric conversions in two distinct ways depending on the operand’s type and its internal ToPrimitive behavior:
  1. NaN Evaluation: If the operand is a type that coerces to NaN (such as undefined or non-numeric strings), the operation results in NaN (Not-a-Number). This also applies to objects that do possess valid primitive conversions but resolve to non-numeric strings (e.g., an empty object {} converts to "[object Object]", which then coerces to NaN). Once an operand becomes NaN, subsequent decrement operations will continue to yield NaN.
  2. TypeError Exception: The ToNumeric operation will throw a TypeError if the operand is a Symbol (or an object that coerces to a Symbol), or if the operand is an object that entirely lacks a valid primitive conversion (e.g., Object.create(null), or an object where both valueOf and toString return objects instead of primitives).
let undef = undefined;
undef--; 
// undef is NaN

let obj = {};
obj--; 
// obj is NaN (coerces to "[object Object]", then to NaN)

let sym = Symbol("id");
sym--; 
// Throws TypeError: Cannot convert a Symbol value to a number

let nullProto = Object.create(null);
nullProto--; 
// Throws TypeError: Cannot convert object to primitive value

BigInt Compatibility

The -- operator is fully compatible with BigInt primitives. It subtracts 1n from the operand. Because ToNumeric resolves to either a Number or a BigInt, type mixing rules still apply; the operator respects the underlying type without implicitly converting a BigInt to a Number.
let bigVal = 10n;
let bigResult = bigVal--; 
// bigVal is 9n, bigResult is 10n
Master JavaScript with Deep Grasping Methodology!Learn More