It's treating the value as signed, so the top bit is used as the sign bit. Since 0xAA000000 has the top bit set, you're winding up with a negative number. Like most machines, it seems to be representing signed values in two's complement.
In languages that offer them, unsigned values are typically preferred for these kinds of bit operations, because they aren't subject to these concerns. In JavaScript, I'd typically use a library like BigInteger.js to handle integer values outside the normal signed integer range. (Technically, a floating-point value like a typical JavaScript Number
value should be able to represent any value in the range you're interested in, but those aren't really designed for the kinds of bitwise operations that you're trying to perform, so I think a library is going to be easier to work with).
If you definitely always have a 32-bit value (and no larger) and you want an unsigned result, using the zero-fill right shift operator >>> to shift by zero should give the correct result.
var value = 0xAA;
var shifted = (value << 24) >>> 0; // 0xAA000000