8.1 假隨機數
有時候程序员會遇到一些看似簡單的問題:「從特定清單中選擇一部今晚要看的電影」、「選擇彩票的贏家」、「在搖晃智慧型手機時隨機安排播放列表」、「選擇一個加密信息的隨機數」,每次都會有個很合理的問題:那麼,如何獲得這個隨機數呢?
其實,如果你需要獲得「真正的隨機數」,這相當困難。甚至需要在電腦中內建專業的數學協處理器來生成符合「真隨機」要求的數字。
因此程序员設計出自己的解決方案——假隨機數。假隨機數是一種序列,其中的數字乍看之下似乎是隨機的,但專家經過詳細分析可以在其中找到一定的規律性。這樣的數字不適用於加密機密文件,但模擬遊戲中擲骰子是完全可以的。
有很多算法可以生成假隨機數序列,幾乎所有這些算法都基於前一個數和一些輔助數生成下一個隨機數。
例如,以下程式將在螢幕上顯示1000個不重複的數字:
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);
}
順便說一句,我們說的不是單一的假隨機數,而是這樣的數字的序列,因為光看一個數字是無法判斷它是否隨機的。
隨機數可以用不同的方法來獲得:
function getNextRandom() {
return 4; # 這絕對是一個隨機數(我用骰子扔出來的)
}
8.2 switch運算子
運算子 switch 用於根據表達式的值來執行幾個代碼塊中的一個。它在需要將一個值與多個可能選項進行比較時特別有用。
語法:
switch(expression) {
case value1:
// 當 expression === value1 時執行的代碼
break;
case value2:
// 當 expression === value2 時執行的代碼
break;
// ...
default:
// 當沒有值匹配時執行的代碼
}
範例:
let day = 3;
let dayName;
switch (day) {
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
case 4:
dayName = "星期四";
break;
case 5:
dayName = "星期五";
break;
case 6:
dayName = "星期六";
break;
case 7:
dayName = "星期日";
break;
default:
dayName = "無效的日子";
}
console.log(dayName); // "星期三"
8.3 運算子 ??
運算子 ??,或稱nullish coalescing operator,用於當左運算項為 null 或 undefined 時分配預設值。它允許避免為其它虛值如 0、false 或空字串 ("") 分配預設值。
語法:
let result = value1 ?? value2;
如果 value1 不是 null 或 undefined,result 將為 value1。否則,result 將為 value2。
範例:
let foo = null ?? 'default';
console.log(foo); // 'default'
let bar = 0 ?? 'default';
console.log(bar); // 0 (0 不是 null 或 undefined)
let baz = undefined ?? 'default';
console.log(baz); // 'default'
與邏輯或 (||) 的區別
運算子 || 也可以用於設定預設值,但它會返回任何虛值的右運算項,如 0、"" 或 NaN。
比較範例:
let value = 0 || 'default';
console.log(value); // 'default' (因為 0 是虛值)
let value2 = 0 ?? 'default';
console.log(value2); // 0 (因為 0 不是 null 或 undefined)
應用
運算子 ?? 在需要只為 null 或 undefined 設置預設值時特別有用,但保留其它虛值,如 0 或 ""。
實際使用範例
範例1. 配置對象中的預設值:
function configure(settings) {
settings = settings ?? {};
let timeout = settings.timeout ?? 1000;
let color = settings.color ?? 'blue';
// 其他配置
}
範例2. 函數的預設參數:
function printMessage(message) {
message = message ?? 'No message provided';
console.log(message);
}
printMessage(null); // 'No message provided'
printMessage('Hello'); // 'Hello'
使用運算子 ?? 可以讓代碼更加簡潔和可預測,特別是在只有缺少值 (null 或 undefined) 需要考慮的情況下。
GO TO FULL VERSION