跳至內容
Astera Technology

const 鎖住名稱,不代表物件不能改

先改物件內容,再試把 const 名稱指向另一物件。

下載完整個案資料及參考答案 ↓

先追這段程式

草稿用 const 儲存。改標題和換掉整個物件,看似都是修改,實際觸及的位置不同。先估結果,再讀輸出。

完整原始程式
const note={title:'Draft'}; note.title='Revised';
let reassignment; try{note={title:'Other'};}catch(error){reassignment=error.name;}
console.log(JSON.stringify({title:note.title,reassignment}));
確實的 console 輸出
{"title":"Revised","reassignment":"TypeError"}
值與執行位置
操作改動位置結果
note.title='Revised'物件屬性Revised
note={...}const 綁定TypeError

結果為何如此

note 仍指向原有物件;title 賦值改的是物件內部。把新物件賦給 note 才是重新綁定,會拋出 TypeError。例子只記錯誤名稱,不依賴各引擎的訊息字眼。

比較另一種寫法

const 沒有凍結內容;以下連外層物件也 freeze 了,內層 style 仍能改。

另開的有限例子
const note=Object.freeze({style:{ink:'green'}});
note.style.ink='purple';
console.log(JSON.stringify({outerFrozen:Object.isFrozen(note),innerFrozen:Object.isFrozen(note.style),ink:note.style.ink}));
另一寫法的輸出
{"outerFrozen":true,"innerFrozen":false,"ink":"purple"}

試清邊界

改用 let,能否令 note.title 不可修改?

查看參考答案

不能。let 還容許重新綁定,不會保護物件。要保留原值,需另外訂複製或凍結方式。

重新建立的邊界例子
'use strict';
const note=Object.freeze({title:'Draft'});let errorName;
try{note.title='Revised';}catch(error){errorName=error.name;}
console.log(JSON.stringify({title:note.title,errorName}));
邊界例子的輸出
{"title":"Draft","errorName":"TypeError"}

原始例子檔案