對象和陣列的比較:
const arr1 = [];
const arr2 = arr1;
console.log(arr1 === arr2); // true
console.log([] === []); // false
解釋:第一次比較為 true
是因為 arr1
和 arr2
指向同一個參考。但 [] === []
為 false
因為兩個新的陣列意味著兩個不同的參考。
任意型別 (any
):
let something: any = "Hello";
something = 42; // No error, but risky!
解釋:使用 any
型別允許變數有任何值,但這避免了 TypeScript 的型別檢查,可能導致執行時的問題。
null
和 undefined
:
let name: string | null = "John";
name = null; // Allowed
解釋:如果沒有 | null
, 賦值為 null
會是錯誤。必須明確地包含 null
型別。
函數型別:
function greet(name?: string) {
return "Hello, " + name; // Might be "Hello, undefined"
}
解釋:參數 name
是可選的,但函數內沒有檢查它是否被提供。
隱式 any
:
let something; // Implicit 'any' type
something = "Hello";
something = 42;
解釋:沒有明確的型別,something
會被認為是 any
,可能會導致不預期的行為。
索引型別:
const person = { name: "John" };
console.log(person.age); // Error, 'age' doesn't exist
解釋:試圖訪問不存在的屬性 age
會導致錯誤。
型別斷言:
const value: unknown = "Hello";
const length: number = (value as string).length; // Assumes value is a string
解釋:使用型別斷言假設 value
是一個字串,但如果它不是,這會導致錯誤。
不夠嚴格的 tsconfig
設定:
{
"compilerOptions": {
"strict": false
}
}
解釋:strict
設為 false
使 TypeScript 更加寬容,但可能忽略某些錯誤。
模組和命名空間:
// file1.ts
export const name = "John";
// file2.ts
import { nam } from './file1'; // Typo in imported variable
解釋:試圖從 file1.ts
導入一個名為 nam
的變數會導致錯誤,因為正確的名稱是 name
。
陣列的 map
, filter
, reduce
方法:
const numbers = [1, 2, 3];
const doubled = numbers.map(n => { n * 2 }); // Missing 'return', results in an array of 'undefined'
解釋:回調函數缺少 return
關鍵字,所以它返回 undefined
。
這些範例和解釋提供了 TypeScript 和 JavaScript 中一些常見問題的深入了解。不過幸好現在大部分的 TypeScript 已經會出現錯誤訊息來確保我們沒有遇到上述的議題。