」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > JavaScript 中的物件可變性

JavaScript 中的物件可變性

發佈於2024-08-19
瀏覽:114

Object Mutability in Javascript

物件可變性

可變性是改變值的能力。可變值可以更改,不可變值則無法更改。 一個常見的誤解是“const”關鍵字使變數不可變。

常量

實際上,「const」只阻止重新分配。對於非物件類型,值只能透過重新分配來更改,因此用“const”聲明它們實際上使它們不可變。 例如,考慮以下程式碼:

const num = 5;
num = 7; // illegal reassignment of const variable

在此程式碼中無法變更 num 的值。請注意,使用或 -- 仍然被視為重新分配,如果我們嘗試在使用 const.
聲明的變數上使用它們,錯誤訊息中會指出這一點

const num = 5;
num  ;//illegal reassignment of constant

產生的錯誤是:

Uncaught TypeError: Assignment to constant variable.

const 物件可以是可變的

物件在可變性方面有著根本的不同,因為它們的值可以在不重新分配變數的情況下改變。請注意,「const」不會阻止屬性的重新分配。僅阻止變數名稱重新分配。

const obj = {num: 5};
obj.num = 7; //legal
obj = {num: 7}; //illegal reassignment 

物件還可以具有更改內部值的方法。

const obj = {
    num: 5,
    increment(){
        this.num  ;
    }
}
obj.increment();
console.log(obj.num); //6

使物件不可變

透過以「const」宣告物件並使用 Object.freeze() 可以使物件實際上不可變。

const obj = {num: 5};
Object.freeze(obj);
obj.num = 7; // doesn't change
console.log(obj.num);// still 5

請注意,如果我們使用嚴格模式,嘗試更改 num 值實際上會導致崩潰,並顯示以下錯誤訊息:

Cannot assign to read only property 'num'

使用不含「const」的 Object.freeze() 足以使該物件不可變。但是,它不會使變數名稱不可變。

let obj = {num: 5};
Object.freeze(obj);
obj = {num: 5}; // new object with old name
obj.num = 7; // changes successfully
console.log(obj.num);// 7

此版本的程式碼中發生的情況是 obj 被重新指派。 freeze() 應用於共享相同名稱的前一個對象,但新對象從未被凍結,因此它是可變的。

密封物體

有時您可能希望允許更改物件中的值,但又不想允許新增或刪除屬性。 這可以透過使用 Object.seal().
來實現

let obj = {num: 5};
Object.seal(obj);
obj.num = 7; // changes
console.log(obj.num);// 7
obj.newValue = 42; //cannot add new property to sealed object
console.log(obj.newValue);//undefined
delete obj.num; //cannot delete property from sealed object
console.log(obj.num);// still exists and is 7

精細化控制

冷凍和密封適用於整個物體。如果您想要讓特定屬性不可變,可以使用defineProperty() 或defineProperties() 來完成。這兩者之間的選擇取決於您想要影響單一屬性還是多個屬性。

const obj = {};
Object.defineProperty(obj, 'num',{
    value: 5,
    writable: false,
    configurable: false
});
obj.num = 7; // Cannot change value because writable is false
delete obj.num; // Cannot delete because configurable is false
console.log(obj.num);//Still exists and is 5

本例中定義了一個新屬性,但也可以對現有屬性使用defineProperty()。 請注意,如果「configurable」之前設定為 false,則無法將其變更為 true,但如果最初為 true,則可以將其設為 false,因為此變更算作一種配置。

結論

在大多數情況下,您不需要保證物件是不可變的。當出現這種需要時,通常凍結物件就足夠了,但是如果出現這種需要,我們還有其他選項可以進行更精細的控制。

版本聲明 本文轉載於:https://dev.to/chooking/object-mutability-in-javascript-1nk4?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3