1. Áp dụng phong cách lập trình kiểu mạnh (strong-typing style)
Mặc dù JavaScript là ngôn ngữ động và yếu kiểu, nhưng điều đó không có nghĩa là bạn nên viết mã một cách tùy tiện. Việc tuân thủ các nguyên tắc giống như trong ngôn ngữ mạnh kiểu sẽ giúp mã dễ đọc, dễ bảo trì và hiệu quả hơn.
(1) Khởi tạo giá trị mặc định khi khai báo biến
Tránh khai báo biến mà không gán giá trị:
var total;
var message;
var config;
Nên gán giá trị khởi tạo phù hợp với mục đích sử dụng:
var total = 0;
var message = '';
var config = null;
Việc này giúp người đọc hiểu rõ loại dữ liệu dự kiến và hỗ trợ engine JavaScript tối ưu hóa tốt hơn.
(2) Tránh thay đổi kiểu dữ liệu của biến
Không nên tái sử dụng cùng một biến cho nhiều kiểu dữ liệu khác nhau:
var id = 123;
id = "user_" + id; // Không nên
Thay vào đó, hãy dùng biến mới:
var userId = 123;
var userKey = "user_" + userId;
(3) Đảm bảo kiểu trả về của hàm nhất quán
Hàm không nên trả về nhiều kiểu khác nhau:
function calculateBonus(sales) {
if (sales < 0) return ""; // string
return sales * 0.1; // number
}
Nên thống nhất kiểu trả về và dùng giá trị đặc biệt để biểu thị lỗi:
function calculateBonus(sales) {
if (sales < 0) return -1; // luôn là number
return sales * 0.1;
}
2. Tối ưu việc tra cứu phạm vi (scope lookup)
(1) Tránh rò rỉ biến ra global scope
Đoạn mã sau chạy trong global scope — chậm và gây ô nhiễm môi trường toàn cục:
var container = document.getElementById('app');
container.style.display = 'block';
Nên bao bọc trong IIFE hoặc khối mã riêng:
(function() {
var container = document.getElementById('app');
container.style.display = 'block';
})();
(2) Hạn chế lạm dụng closure sâu
Khi một biến được truy cập từ closure cha, engine phải tìm kiếm qua nhiều tầng scope. Thay vì:
function compute(value) {
value += 10;
function helper() {
return value * 2;
}
return helper();
}
Hãy truyền giá trị trực tiếp:
function compute(value) {
value += 10;
function helper(v) {
return v * 2;
}
return helper(value);
}
Tương tự, khi truy cập nhiều lần vào thuộc tính của đối tượng toàn cục, hãy lưu vào biến cục bộ:
var loc = window.location;
if (loc.protocol === 'https:') {
var wsUrl = `wss://api.example.com${loc.pathname}${loc.search}`;
}
3. Luôn dùng === thay vì ==
Toán tử == thực hiện ép kiểu ngầm định, dẫn đến hành vi khó lường:
0 == '' // true
null == undefined // true
true == 1 // true
Các so sánh trên đều trả về false nếu dùng ===, phản ánh đúng bản chất logic. Ngoài ra, công cụ lint như ESLint/JSLint thường cảnh báo khi dùng ==.
Khi cần so sánh giữa các kiểu khác nhau, hãy ép kiểu rõ ràng:
var pageStr = "5";
if (parseInt(pageStr, 10) === 1) { ... }
4. Gộp biểu thức để mã ngắn gọn hơn
(1) Dùng toán tử ba ngôi thay if-else đơn giản
function getDiscount(items) {
return items < 0 ? -1 : items * 10;
}
(2) Tận dụng chuỗi gán (chained assignment)
let a, b, c;
a = b = c = { status: 'active' };
(3) Gán và kiểm tra trong cùng biểu thức
let input;
if ((input = parseFloat(form.value)) >= 0) {
console.log(`Giá trị hợp lệ: ${input}`);
}
5. Loại bỏ "số ma" (magic numbers/values)
Thay vì gọi hàm với các giá trị vô danh:
showDialog("seller", "sell", 5, true);
Hãy đặt tên cho các hằng số:
const USER_TYPE = "seller";
const DIALOG_MODE = "sell";
const MAX_QUESTIONS = 5;
const AUTO_RELOAD = true;
showDialog(USER_TYPE, DIALOG_MODE, MAX_QUESTIONS, AUTO_RELOAD);
6. Tận dụng ES6 để viết mã sạch hơn
(1) Hàm mũi tên (arrow functions)
// Sắp xếp giảm dần
numbers.sort((a, b) => b - a);
// Callback ngắn
setTimeout(() => console.log("Xong!"), 1000);
(2) Lớp (class) thay cho prototype
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
grow() {
this.age++;
}
}
(3) Template literals
const html = `
<div>
<span>${userName}</span>
</div>
`;
const apiUrl = `/api/data?page=${page}&lang=${lang}`;
(4) Biến block-scoped với let/const
Vấn đề kinh điển với var trong vòng lặp:
var tasks = [];
for (var i = 0; i < 3; i++) {
tasks.push(() => console.log(i)); // in 3, 3, 3
}
Giải pháp đơn giản với let:
for (let i = 0; i < 3; i++) {
tasks.push(() => console.log(i)); // in 0, 1, 2
}
Nhờ let tạo binding mới ở mỗi lần lặp, closure ghi lại đúng giá trị mong muốn.