8.1 Số giả ngẫu nhiên
Đôi khi lập trình viên gặp phải những nhiệm vụ tưởng chừng như đơn giản: “chọn ngẫu nhiên một bộ phim cho tối nay từ một danh sách nhất định”, “chọn người thắng cuộc xổ số”, “trộn danh sách bài hát khi lắc điện thoại”, “chọn số ngẫu nhiên để mã hóa thông điệp”, và mỗi lần họ đều có một câu hỏi rất hợp lý: làm thế nào để có được số ngẫu nhiên này?
Thực ra, nếu bạn cần một "số ngẫu nhiên thực sự", việc này khá là khó. Đến mức người ta phải gắn các bộ xử lý toán học đặc biệt vào máy tính, những bộ xử lý này có khả năng tạo ra những số như thế với tất cả các yêu cầu về "ngẫu nhiên thực sự".
Vì thế, lập trình viên đã nghĩ ra một giải pháp của riêng mình — số giả ngẫu nhiên. Số giả ngẫu nhiên là một dãy số mà thoạt nhìn có vẻ ngẫu nhiên, nhưng chuyên gia khi phân tích kỹ có thể tìm thấy trong đó những quy luật nhất định. Để mã hóa tài liệu bí mật, những số này không phù hợp, nhưng để mô phỏng việc quăng xúc xắc trong trò chơi — hoàn toàn có thể.
Có nhiều thuật toán để tạo ra dãy số giả ngẫu nhiên và hầu hết chúng đều tạo ra số ngẫu nhiên tiếp theo dựa trên số trước đó và một vài số phụ trợ khác.
Ví dụ, chương trình này sẽ in ra màn hình 1000 số không trùng lặp:
let a = 41;
let c = 11119;
let m = 11113;
let seed = 1;
function getNextRandom() {
seed = (a * seed + c) % m;
return seed;
}
for (let t = 0; t < 1000; t++) {
let x = getNextRandom();
console.log(x);
}
Nhân tiện, chúng ta không nói về số giả ngẫu nhiên, mà là về dãy số như thế, vì nhìn vào một số thì không thể hiểu được nó là ngẫu nhiên hay không.
Số ngẫu nhiên thực sự có thể nhận được bằng nhiều cách khác nhau:
function getNextRandom() {
return 4; # đây chắc chắn là một số ngẫu nhiên (tôi đã quăng nó bằng xúc xắc)
}
8.2 Opertor switch
Opertor switch
được sử dụng để thực thi một trong nhiều khối mã dựa trên giá trị của biểu thức. Nó đặc biệt hữu ích khi cần so sánh một giá trị với nhiều lựa chọn có thể xảy ra.
Cú pháp:
switch(expression) {
case value1:
// mã, sẽ được thực thi nếu expression === value1
break;
case value2:
// mã, sẽ được thực thi nếu expression === value2
break;
// ...
default:
// mã, sẽ được thực thi nếu không có giá trị nào trùng khớp
}
Ví dụ:
let day = 3;
let dayName;
switch (day) {
case 1:
dayName = "Thứ hai";
break;
case 2:
dayName = "Thứ ba";
break;
case 3:
dayName = "Thứ tư";
break;
case 4:
dayName = "Thứ năm";
break;
case 5:
dayName = "Thứ sáu";
break;
case 6:
dayName = "Thứ bảy";
break;
case 7:
dayName = "Chủ nhật";
break;
default:
dayName = "Ngày không hợp lệ";
}
console.log(dayName); // "Thứ tư"
8.3 Opertor ??
Opertor ??
, hay nullish coalescing operator, được sử dụng để gán giá trị mặc định nếu toán hạng bên trái là null
hoặc undefined
. Nó cho phép tránh việc áp dụng giá trị mặc định cho các giá trị sai khác, như 0
, false
, hay chuỗi rỗng (""
).
Cú pháp:
let result = value1 ?? value2;
Nếu value1 không phải null
hoặc undefined
, result sẽ là value1. Nếu không, result sẽ là value2.
Ví dụ:
let foo = null ?? 'default';
console.log(foo); // 'default'
let bar = 0 ?? 'default';
console.log(bar); // 0 (0 không phải là null hoặc undefined)
let baz = undefined ?? 'default';
console.log(baz); // 'default'
Khác biệt so với logic OR (||)
Opertor ||
cũng có thể được sử dụng để đặt giá trị mặc định, nhưng nó trả về toán hạng bên phải cho bất kỳ giá trị sai nào, như 0
, ""
, hoặc NaN
.
Ví dụ so sánh:
let value = 0 || 'default';
console.log(value); // 'default' (vì 0 là giá trị sai)
let value2 = 0 ?? 'default';
console.log(value2); // 0 (vì 0 không phải là null hoặc undefined)
Ứng dụng
Opertor ??
hữu ích trong các tình huống cần đặt giá trị mặc định chỉ cho null
hoặc undefined
, nhưng giữ nguyên các giá trị sai, như 0
hoặc ""
.
Ví dụ thực tế về sử dụng
Ví dụ 1. Giá trị mặc định trong các đối tượng cấu hình:
function configure(settings) {
settings = settings ?? {};
let timeout = settings.timeout ?? 1000;
let color = settings.color ?? 'blue';
// logic cài đặt còn lại
}
Ví dụ 2. Tham số mặc định cho các hàm:
function printMessage(message) {
message = message ?? 'No message provided';
console.log(message);
}
printMessage(null); // 'No message provided'
printMessage('Hello'); // 'Hello'
Sử dụng opertor ??
cho phép viết mã sạch hơn và dễ đoán hơn, đặc biệt trong các tình huống mà việc xem xét chỉ sự vắng mặt của giá trị (null
hoặc undefined
) là quan trọng.
GO TO FULL VERSION