Từ ES2016 (ES7), JavaScript hỗ trợ toán tử lũy thừa ** — cú pháp ngắn gọn, dễ đọc thay cho Math.pow(). Toán tử này cũng tồn tại trong Python, Ruby, và nhiều ngôn ngữ khác.
Cú pháp cơ bản
base ** exponent // base mũ exponent
// Ví dụ
2 ** 3 // 8
5 ** 2 // 25
10 ** -1 // 0.1
2 ** 3 ** 2 // 2 ** (3 ** 2) = 2 ** 9 = 512 (kết hợp từ phải sang trái)
So sánh với Math.pow()
| Đặc điểm | ** | Math.pow() |
|---|---|---|
| Cú pháp | Infix (giữa 2 toán hạng) | Function call |
| Độ đọc | Cao, tự nhiên toán học | Thấp hơn |
| Hỗ trợ BigInt | Có (ES2020) | Không |
| Cơ số âm | Cần ngoặc: (-2) ** 2 | Không cần: Math.pow(-2, 2) |
| Hiệu năng | Tương đương | Tương đương |
Ví dụ cơ bản
<html>
<body>
<script>
const res1 = Math.pow(3, 2); // 9
const res2 = 3 ** 2; // 9
const res3 = 2 ** 10; // 1024
const res4 = 4 ** 0.5; // 2 (căn bậc 2)
document.write(res1 + "<br>" + res2 + "<br>" + res3 + "<br>" + res4);
</script>
</body>
</html>
Cạm bẫy: Cơ số âm (Negative Base)
Đây là điểm khác biệt quan trọng nhất:
<html>
<body>
<script>
// Math.pow - OK
document.write(Math.pow(-3, 2) + "<br>"); // 9
// Toán tử ** - CẦN NGỎAC
document.write((-3) ** 2 + "<br>"); // 9 ✓
// KHÔNG NGỎAC → LỖI CÚ PHÁP
// document.write(-3 ** 2); // SyntaxError: Unary operator used immediately before exponentiation expression
// Giải thích: -3 ** 2 được hiểu là -(3 ** 2) = -9
// Nhưng JS cấm viết tắt này để tránh nhầm lẫn, bắt buộc dùng ngoặc
</script>
</body>
</html>
Hỗ trợ BigInt (ES2020+)
// Chỉ ** hỗ trợ BigInt, Math.pow() KHÔNG
const big = 2n ** 100n; // 1267650600228229401496703205376n
// Math.pow(2, 100) // Chỉ trả về Number, mất độ chính xác
Toán tử gán lũy thừa (**=)
let x = 2;
x **= 3; // x = x ** 3 = 8
console.log(x); // 8
// Tương đương
x = x ** 3;
Khuyến nghị thực tế
- Ưu tiên
**cho code hiện đại — ngắn gọn, hỗ trợ BigInt, dễ đọc. - Luôn bọc cơ số âm trong ngoặc:
(-x) ** y. - Dùng
Math.pow()chỉ khi cần tương thích môi trường cực cũ (pre-ES2016). - Cẩn thận với độ ưu tiên:
-x ** ylà lỗi,-(x ** y)là âm của lũy thừa,(-x) ** ylà lũy thừa của số âm.