C++ 的 const 是深層不可變,JS 的 const 只防重新賦值
JS 的
const只防變數被重新賦值,防不住物件內部被改(要靠Object.freeze())。 C++ 的const是「唯讀」,而且由編譯器在編譯期強制——初始化完成之後,任何嘗試修改它的程式碼都會直接噴錯。
// JavaScript
const arr = [1, 2, 3];
arr.push(4); // ✅ 完全合法!const 只能防 arr = ...,防不了內容被改// C++
const std::vector<int> arr = {1, 2, 3};
arr.push_back(4); // ❌ 編譯錯誤!編譯器禁止呼叫任何可能修改 arr 的成員函式
arr[0] = 10; // ❌ 編譯錯誤!裡面的值也是 const把一個物件宣告為 const,它的直接成員全部跟著變成不可變。
const & 傳參:零拷貝加上唯讀保證
解題時最常見的參數寫法:
void process(const std::vector<int>& nums) {
// nums[0] = 99; // ❌ 編譯錯誤
}兩個關鍵字各做一件事:
| 作用 | |
|---|---|
& | 不複製整份容器——省記憶體、省時間, 傳遞 |
const | 保證唯讀,等於告訴呼叫者「這個函式不會動你的資料」 |
這是 C++ 裡同時拿到高效能與不可變保證的標準寫法。
一個重要的例外:const 穿不過指標
「宣告 const 就全面不可變」只對直接成員成立。const 不具傳遞性——它管得到指標本身,管不到指標指向的東西:
struct S { int* p; };
const S s;
// s.p = otherPtr; // ❌ 指標本身不能改(它變成 int* const)
*s.p = 42; // ✅ 合法!指向的內容照改const 到底鎖住哪一半,取決於它寫在哪裡——見 指標的 const 位置決定是指標不可變還是內容不可變。
JS vs C++ 對照
| 特性 | JavaScript | C++ |
|---|---|---|
| 宣告語法 | const x = ... | const int x = ... |
| 物件/陣列內部成員 | 預設仍可變(需 Object.freeze()) | 宣告 const 即不可變(但穿不過指標) |
| 檢查時機 | 執行期 | 編譯期直接報錯 |
| 編譯期常數 | 無 | constexpr,見 constexpr 是編譯期常數,const 只是執行期唯讀 |
| 函式參數唯讀傳遞 | 無原生防護 | const Type&(零拷貝且強制唯讀) |
最後一列要講清楚 JS 那半邊:JS 是「把參照當成值傳」,不是 pass-by-reference——
function f(o) {
o.x = 1; // ✅ 影響呼叫端(改的是同一個物件)
o = {}; // ❌ 不影響呼叫端(真正的引用傳遞會影響)
}所以 JS 缺的不是「引用傳遞」,是沒有辦法在語言層面禁止被呼叫的函式去改你傳進去的物件。