> ## 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.

# JavaScript Unary Minus

The `-` operator in JavaScript functions as both a binary subtraction operator and a unary negation operator, depending on its execution context (arity). In both forms, it implicitly coerces non-numeric operands to numeric primitives (`Number` or `BigInt`) via the abstract `ToNumeric` operation before evaluation.

## Binary Subtraction Operator

As a binary operator, `-` computes the mathematical difference between two operands.

```javascript theme={"dark"}
leftOperand - rightOperand
```

**Evaluation Mechanics:**

1. Both `leftOperand` and `rightOperand` are evaluated.
2. Both values are passed through the abstract `ToNumeric` operation.
3. If the types of the two resulting primitives differ (e.g., one is a `Number` and the other is a `BigInt`), a `TypeError` is thrown.
4. The right numeric value is subtracted from the left numeric value according to IEEE 754 double-precision floating-point arithmetic (or BigInt arithmetic).

```javascript theme={"dark"}
10 - 3;         // 7
10.5 - 0.5;     // 10
10n - 3n;       // 7n (BigInt arithmetic)
10n - 3;        // TypeError: Cannot mix BigInt and other types
```

## Unary Negation Operator

As a unary operator, `-` precedes a single operand. It coerces the operand to a numeric type and inverts its algebraic sign.

```javascript theme={"dark"}
-operand
```

**Evaluation Mechanics:**

1. The `operand` is evaluated.
2. The value is passed through the abstract `ToNumeric` operation.
3. If the resulting value is `NaN`, the result remains `NaN`.
4. Otherwise, the sign of the numeric value is inverted.
5. **Edge Case for Zero:** For `Number` types, negating `0` yields `-0` (JavaScript distinguishes between `+0` and `-0`). However, `BigInt` does not possess a negative zero concept; negating `0n` evaluates strictly to `0n`.

```javascript theme={"dark"}
-5;             // -5
-(-5);          // 5
-0;             // -0 
-0n;            // 0n (BigInt zero cannot be negative)
-10n;           // -10n
```

## Implicit Type Coercion (`ToNumeric`)

Because the `-` operator is strictly mathematical, it forces type coercion on non-numeric types. When applying the `-` operator to non-numeric primitives, the JavaScript engine applies `ToNumeric`, which delegates to `ToNumber` for standard primitives:

```javascript theme={"dark"}
// Booleans
5 - true;       // 4 (true coerces to 1)
5 - false;      // 5 (false coerces to 0)

// Null and Undefined
5 - null;       // 5 (null coerces to 0)
5 - undefined;  // NaN (undefined coerces to NaN)

// Strings
5 - "2";        // 3 (numeric strings coerce to their number equivalent)
5 - "";         // 5 (empty strings coerce to 0)
5 - "foo";      // NaN (non-numeric strings coerce to NaN)

// Unary coercion examples
-"42";          // -42
-true;          // -1
-null;          // -0
```

## Object Coercion

When an operand is an Object, JavaScript attempts to convert it to a primitive value using the abstract `ToPrimitive` operation, prioritizing the `number` hint.

The resolution follows strict rules:

1. If the object defines a `[Symbol.toPrimitive]` method, it is called exclusively with the `"number"` hint. If this method returns an object instead of a primitive, a `TypeError` is thrown immediately (it does *not* fall back to other methods).
2. If `[Symbol.toPrimitive]` is absent, the engine falls back to calling `valueOf()`. If `valueOf()` returns a primitive, that value is used.
3. If `valueOf()` is absent or returns an object, the engine falls back to calling `toString()`.

Once a primitive is successfully returned, it is processed by `ToNumeric`. If the returned primitive is a `BigInt`, `ToNumeric` returns it directly. If the primitive is any other type, it is subjected to `ToNumber` coercion rules.

```javascript theme={"dark"}
const objWithSymbol = {
  [Symbol.toPrimitive](hint) {
    return 10n; // Returns a BigInt directly
  }
};
25n - objWithSymbol; // 15n

const objWithValueOf = {
  valueOf: () => "10" // Returns a string, which is then passed to ToNumber
};
25 - objWithValueOf; // 15

const date = new Date("2023-01-01T00:00:00Z");
// Dates coerce to their epoch timestamp in milliseconds via valueOf()
date - 1000;    // 1672531199000 

// Arrays (rely on toString() fallback since valueOf() returns the array itself)
5 - [2];        // 3 ([2] -> "2" -> 2)
5 - [2, 3];     // NaN ([2, 3] -> "2,3" -> NaN)
5 - [];         // 5 ([] -> "" -> 0)
```

## IEEE 754 Edge Cases

Because JavaScript Numbers are double-precision floats, the `-` operator adheres to specific IEEE 754 rules regarding `Infinity`, `-Infinity`, and `NaN`:

```javascript theme={"dark"}
Infinity - 5;            // Infinity
Infinity - Infinity;     // NaN
-Infinity - Infinity;    // -Infinity

// Any arithmetic operation involving NaN results in NaN
NaN - 5;                 // NaN
5 - NaN;                 // NaN

// Zero arithmetic
+0 - +0;                 // +0
-0 - -0;                 // +0
-0 - +0;                 // -0
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor JavaScript Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
