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 <<= (Left Shift Assignment) operator performs a bitwise left shift on its left operand by the number of bits specified by its right operand, and assigns the resulting value to the left operand.

Syntax

x <<= y
Equivalent to: x = x << y

Execution Mechanics

The behavior of the <<= operator depends strictly on the types of its evaluated operands. JavaScript supports bitwise operations on both Number and BigInt types, but mixing the two throws a TypeError.

For Number Operands

When operating on standard JavaScript numbers (or values coerced to numbers), the engine performs the following sequence:
  1. Type Coercion: Both operands are implicitly coerced to 32-bit integers. The left operand is converted to a 32-bit signed integer (ToInt32), and the right operand is converted to a 32-bit unsigned integer (ToUint32).
  2. Shift Masking: The right operand is masked with 0x1F (bitwise AND with 31). This applies a modulo 32 operation, ensuring the shift amount is strictly between 0 and 31 bits. Shifting by 32 bits or more wraps around.
  3. Bit Manipulation: The 32-bit binary representation of the left operand is shifted to the left by the calculated number of bits.
  4. Zero-Filling: Vacated bit positions on the right side are filled with zeros (0).
  5. Truncation: Any bits shifted beyond the 32nd bit boundary on the left are discarded.
  6. Assignment: The resulting 32-bit signed integer is assigned back to the left operand.

For BigInt Operands

When both operands are BigInt primitives, the 32-bit limitations are bypassed:
  1. Validation: The engine checks the right operand. If the shift amount is negative, a RangeError is thrown.
  2. Bit Manipulation: The left operand is shifted left by the exact, unmasked number of bits specified by the right operand.
  3. Zero-Filling: Vacated bit positions on the right are filled with zeros (0).
  4. No Truncation or Masking: The right operand is not masked with 0x1F, and the result is not truncated to 32 bits. The resulting binary representation grows to accommodate the shifted magnitude.
  5. Assignment: The resulting BigInt is assigned back to the left operand.

Mechanical Examples

Basic Shift (Number)
let a = 5;      // 32-bit binary: 00000000000000000000000000000101
a <<= 2;        // Shifts left by 2 bits, filling right with 00
console.log(a); // Output: 20
                // 32-bit binary: 00000000000000000000000000010100
Modulo 32 Behavior (Number)
let b = 1;      // 32-bit binary: 00000000000000000000000000000001
b <<= 33;       // 33 & 0x1F = 1. Shifts left by 1 bit.
console.log(b); // Output: 2
                // 32-bit binary: 00000000000000000000000000000010
Unbounded Shift (BigInt)
let c = 1n;     
c <<= 33n;      // No modulo 32 masking, no 32-bit truncation.
console.log(c); // Output: 8589934592n
Sign Bit Overflow (Number)
let d = 1073741824; // 32-bit binary: 01000000000000000000000000000000
d <<= 1;            // The 1 shifts into the sign bit (32nd bit)
console.log(d);     // Output: -2147483648
                    // 32-bit binary: 10000000000000000000000000000000
Implicit Type Coercion (Number)
let e = "3";    // Coerced to ToInt32(3)
e <<= "2";      // Coerced to ToUint32(2)
console.log(e); // Output: 12 (Type is now Number)
Type Mixing Error
let f = 5n;
f <<= 2;        // TypeError: Cannot mix BigInt and other types
Master JavaScript with Deep Grasping Methodology!Learn More