跳至主要内容

JavaScript 解題常用語法複習

基本語法

變數宣告

let x = 5;        // 可變變數
const y = 10; // 不可變常數
var z = 15; // 舊式宣告(盡量避免)

資料型別檢查

typeof variable;           // 回傳型別字串
Array.isArray(arr); // 檢查是否為陣列
Number.isInteger(num); // 檢查是否為整數

數字運算(整數、浮點數)⭐⭐⭐

基本算術運算(超高頻)

// 基本運算子 ⭐
let a = 10, b = 3;
let add = a + b; // 13(加法)
let sub = a - b; // 7(減法)
let mul = a * b; // 30(乘法)
let div = a / b; // 3.3333...(除法,會產生浮點數)
let mod = a % b; // 1(取餘數/模運算)⭐
let square = a ** 2; // 100(使用指數運算子,ES2016+)

取整運算(超高頻)

// 各種取整方式 ⭐
Math.floor(4.7); // 4(向下取整,無條件捨去)
Math.ceil(4.1); // 5(向上取整,無條件進位)
Math.round(4.5); // 5(四捨五入)

// 整數除法(超常用)⭐
Math.floor(17 / 5); // 3(整數除法結果)
Math.floor(-4.7); // -5(注意:負數向下取整)

// 奇偶數判斷 ⭐
num % 2 === 0; // 偶數
num % 2 === 1; // 奇數

型別轉換(超高頻)

// 字串轉數字 ⭐
Number("123.45"); // 回傳 123.45(推薦,嚴格轉換)
Number("abc"); // ❌ 回傳 NaN(不是數字)
parseFloat("123.45"); // 回傳 123.45
parseFloat("123.45abc"); // 回傳 123.45(忽略後面文字)
+"123.45"; // 123.45(一元加號,簡潔寫法,實際上是呼叫 Number(...))

// 陣列批量轉換 ⭐
["1.2", "3.4"].map(Number); // [1.2, 3.4]

// 數字轉字串 ⭐
String(123); // "123"
(123).toString(); // "123"
123 + ""; // "123"(最簡潔)

常用數值操作(超高頻)

let arr = [1, 2, 3, 4, 5];

// 陣列數值計算 ⭐
let sum = arr.reduce((acc, curr) => acc + curr, 0); // 15(總和)
let max = Math.max(...arr); // 5(最大值)
let min = Math.min(...arr); // 1(最小值)

// 其他常用
Math.abs(-5); // 5(絕對值)
Math.pow(2, 3); // 8(2的3次方)
Math.sqrt(16); // 4(平方根)

陣列操作

基本方法(超高頻)

let arr = [1, 2, 3, 4, 5];

// 新增/移除元素(超常用)
arr.push(6); // 末尾添加 → [1,2,3,4,5,6]
arr.pop(); // 移除末尾 → [1,2,3,4,5]
arr.length; // 陣列長度 → 5

// 合併陣列(常用)
arr.concat([6, 7]); // 合併陣列 → [1,2,3,4,5,6,7]
[...arr1, ...arr2]; // 展開運算子合併(推薦)

// 複製陣列(常用)
let copy = [...arr]; // 淺複製(推薦)
let copy2 = arr.slice(); // 淺複製(傳統寫法)

陣列搜尋與檢查(超高頻)

arr.indexOf(3);           // 找索引,沒找到回傳-1 ⭐
arr.includes(3); // 檢查是否包含,回傳布林值 ⭐
arr.find(x => x > 3); // 找第一個符合條件的元素 ⭐
arr.findIndex(x => x > 3); // 找第一個符合條件的索引

高階陣列方法(解題核心 ⭐⭐⭐)

let numbers = [1, 2, 3, 4, 5];

// map - 轉換每個元素(超高頻)
let doubled = numbers.map(x => x * 2); // [2,4,6,8,10]
let strings = numbers.map(x => x.toString()); // ["1","2","3","4","5"]

// filter - 篩選元素(超高頻)
let evens = numbers.filter(x => x % 2 === 0); // [2,4]
let greaterThan2 = numbers.filter(x => x > 2); // [3,4,5]

// reduce - 累加/合併(高頻)
let sum = numbers.reduce((acc, curr) => acc + curr, 0); // 15
let max = numbers.reduce((acc, curr) => Math.max(acc, curr)); // 5
let product = numbers.reduce((acc, curr) => acc * curr, 1); // 120

// some/every - 條件檢查(中頻)
let hasEven = numbers.some(x => x % 2 === 0); // true
let allPositive = numbers.every(x => x > 0); // true

// sort - 排序(超高頻)
numbers.sort(); // 字典序排序
numbers.sort((a, b) => a - b); // 數字升序 ⭐
numbers.sort((a, b) => b - a); // 數字降序 ⭐

// forEach - 遍歷(中頻,但 for...of 更常用)
numbers.forEach((item, index) => {
console.log(index, item);
});

字串處理

基本操作(超高頻)

let str = "Hello World";

// 基本屬性與方法
str.length; // 11 ⭐
str.charAt(0); // "H" ⭐
str[0]; // "H" (推薦用法) ⭐

// 搜尋(超高頻)
str.indexOf("World"); // 6 ⭐
str.includes("World"); // true ⭐
str.startsWith("Hello"); // true
str.endsWith("World"); // true

字串轉換與處理(高頻)

// 大小寫轉換(高頻)
str.toLowerCase(); // "hello world" ⭐
str.toUpperCase(); // "HELLO WORLD" ⭐

// 分割與合併(超高頻)
str.split(" "); // ["Hello", "World"] ⭐
str.split(""); // ["H","e","l","l","o"," ","W","o","r","l","d"] ⭐
[...str]; // ["H","e","l","l","o"," ","W","o","r","l","d"] ⭐(推薦,正確處理 Unicode)
["Hello", "World"].join(" "); // "Hello World" ⭐
["H","i"].join(""); // "Hi" ⭐

// 去除空白(中頻)
" Hello ".trim(); // "Hello"

// 替換(中頻)
str.replace("World", "JS"); // "Hello JS" (只替換第一個)
str.replaceAll("l", "L"); // "HeLLo WorLd" (替換所有)

迴圈

基本迴圈(超高頻)

let arr = [1, 2, 3, 4, 5];

// for...of(遍歷值)- 推薦 ⭐
for (let value of arr) {
console.log(value);
}

// 傳統 for 迴圈(需要索引時使用)⭐
for (let i = 0; i < arr.length; i++) {
console.log(i, arr[i]);
}

// forEach(中頻,但無法 break)
arr.forEach((item, index) => {
console.log(index, item);
});

迴圈控制(中頻)

// while(中頻)
let i = 0;
while (i < 5) {
console.log(i);
i++;
}

// break 和 continue(中頻)
for (let i = 0; i < 10; i++) {
if (i === 3) continue; // 跳過這次迭代
if (i === 7) break; // 結束迴圈
console.log(i);
}

物件操作

基本操作(中頻)

let obj = {name: "John", age: 30};

// 取值
obj.name; // "John" ⭐
obj["name"]; // "John"(動態鍵名時用)

// 檢查屬性
obj.hasOwnProperty("name"); // true ⭐
"name" in obj; // true

物件方法(中頻)

let obj = {name: "John", age: 30};

// 取得鍵、值、鍵值對(解題常用)
Object.keys(obj); // ["name", "age"] ⭐
Object.values(obj); // ["John", 30] ⭐
Object.entries(obj); // [["name", "John"], ["age", 30]] ⭐

物件屬性操作(中頻)⭐

let obj = {a: 1, b: 2, c: 3};

// 新增/修改屬性 ⭐
obj.d = 4; // 新增屬性 d
obj['e'] = 5; // 用方括號新增屬性(動態鍵名)
obj.a = 10; // 修改屬性 a

// 刪除屬性 ⭐
delete obj.b; // 刪除屬性 b
delete obj['c']; // 用方括號刪除屬性
console.log(obj); // {a: 10, d: 4, e: 5}

// 檢查刪除結果
console.log('b' in obj); // false(屬性已被刪除)
console.log(obj.b); // undefined(被刪除的屬性回傳 undefined)

// 解題中的應用(如 Sliding Window)⭐
let charObj = {};
charObj['a'] = true; // 記錄字符 'a' 存在
charObj['b'] = true; // 記錄字符 'b' 存在

// 移除字符的兩種方式
delete charObj['a']; // 方式1: 完全刪除屬性
charObj['b'] = false; // 方式2: 設為 false

// 條件判斷中的表現
if (charObj['a']) { ... } // false (undefined)
if (charObj['b']) { ... } // false (false)
// 兩種方式在條件判斷中效果相同

// 實際解題範例:字符計數
function countChars(str) {
let count = {};
for (let char of str) {
count[char] = (count[char] || 0) + 1;
}
return count;
}

// 刪除計數為 0 的字符
function removeZeroCounts(count) {
for (let char in count) {
if (count[char] === 0) {
delete count[char]; // 刪除計數為 0 的屬性
}
}
}

條件判斷與比較

比較運算子(超高頻)

// 嚴格相等(建議使用)⭐
x === 5; // 型別和值都要相同
x !== 5; // 不相等

// 數值比較 ⭐
x > 5;
x >= 5;
x < 5;
x <= 5;

邏輯運算(高頻)

// 邏輯運算子 ⭐
x > 0 && x < 10; // AND
x === 1 || x === 2; // OR
!(x > 5); // NOT

// 短路求值(中頻)
let result = x || "default"; // 如果x為falsy,使用"default"
let result2 = x && x.property; // 如果x為truthy,取x.property

區間判斷(超高頻)⭐⭐⭐

// 重要:JavaScript 不支援連續比較運算子
// ❌ 錯誤寫法
25 < score <= 30; // 這樣寫是錯誤的!

// ✅ 正確寫法:使用邏輯運算子 AND(&&)
score > 25 && score <= 30; // 25 < score <= 30
score >= 25 && score <= 30; // 25 <= score <= 30
score > 25 && score < 30; // 25 < score < 30
score >= 25 && score < 30; // 25 <= score < 30

// 常見區間判斷範例
if (score >= 90 && score <= 100) {
console.log("A級");
} else if (score >= 80 && score < 90) {
console.log("B級");
} else if (score >= 70 && score < 80) {
console.log("C級");
} else if (score >= 60 && score < 70) {
console.log("D級");
} else {
console.log("F級");
}

// 在 filter 中使用區間判斷
let numbers = [15, 25, 35, 45, 55];
let inRange = numbers.filter(num => num >= 25 && num <= 45); // [25, 35, 45]

條件語句(超高頻)

// if...else ⭐
if (x > 5) {
console.log("大於5");
} else if (x === 5) {
console.log("等於5");
} else {
console.log("小於5");
}

// 三元運算子 ⭐
let result = (x > 5) ? "大於5" : "不大於5";

Switch 語句(中頻)

// switch 適合:多個固定值的判斷 ⭐
switch (day) {
case 1:
console.log("星期一");
break;
case 2:
console.log("星期二");
break;
case 3:
console.log("星期三");
break;
default:
console.log("其他");
}

// 常見應用:字元/字串判斷
switch (operation) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
default:
return 0;
}

// 重要技巧:多個 case 共享同一個動作 ⭐
function getLetter(s) {
let firstChar = s[0];
switch (firstChar) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return 'A';
case 'b':
case 'c':
case 'd':
case 'f':
case 'g':
return 'B';
case 'h':
case 'j':
case 'k':
case 'l':
case 'm':
return 'C';
default:
return 'D';
}
}

// ❌ 不適合 switch:區間判斷
// switch 無法處理範圍條件,仍需使用 if-else
if (score >= 90) {
console.log("A級");
} else if (score >= 80) {
console.log("B級");
} else if (score >= 70) {
console.log("C級");
} else {
console.log("F級");
}

HackerRank 常用模式

輸入處理(必會)

// 標準輸入處理 ⭐
function processData(input) {
let lines = input.trim().split('\n');
let n = parseInt(lines[0]);

// 處理資料...
console.log(result);
}

// 讀取陣列 ⭐
let arr = lines[1].split(' ').map(Number);

// 讀取多個數字 ⭐
let [a, b, c] = lines[1].split(' ').map(Number);

常見演算法片段(超高頻)

// 計算陣列總和 ⭐
let sum = arr.reduce((acc, curr) => acc + curr, 0);

// 找最大最小值 ⭐
let max = Math.max(...arr);
let min = Math.min(...arr);

// 排序 ⭐
arr.sort((a, b) => a - b); // 升序
arr.sort((a, b) => b - a); // 降序

// 去除重複元素 ⭐
let unique = [...new Set(arr)];

// 計算元素出現次數 ⭐
let count = {};
arr.forEach(item => {
count[item] = (count[item] || 0) + 1;
});

// 反轉陣列/字串 ⭐
let reversed = [...arr].reverse(); // 不改變原陣列
let reversedStr = str.split('').reverse().join('');

// 檢查數字是否為偶數/奇數 ⭐
let isEven = num % 2 === 0;
let isOdd = num % 2 === 1;

輸出格式(必會)

// 基本輸出 ⭐
console.log(result);

// 輸出多個值 ⭐
console.log(results.join(' ')); // 用空格連接
console.log(results.join('\n')); // 用換行連接

Caesar Cipher 字元位移加密(必會題型)⭐⭐⭐

必背方法與公式

// ASCII 轉換(必背)⭐
'A'.charCodeAt(0); // 65 (大寫起始)
'a'.charCodeAt(0); // 97 (小寫起始)
String.fromCharCode(65); // 'A'

// 核心公式:(position + k) % 26
// 字元比較:char >= 'A' && char <= 'Z' (等同於ASCII比較)

標準解法模板 ⭐

function caesarCipher(s, k) {
k = ((k % 26) + 26) % 26; // 處理負數位移
let result = '';

for (let i = 0; i < s.length; i++) {
if (s[i] >= 'A' && s[i] <= 'Z') {
let position = s[i].charCodeAt(0) - 65;
let newPosition = (pos + k) % 26;
result += String.fromCharCode(newPosition + 65);
} else if (s[i] >= 'a' && s[i] <= 'z') {
let position = s[i].charCodeAt(0) - 65;
let newPosition = (pos + k) % 26;
result += String.fromCharCode(newPosition + 97);
} else {
result += s[i]; // 非字母不變
}
}
return result;
}