可變性是改變值的能力。可變值可以更改,不可變值則無法更改。 一個常見的誤解是“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 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,因為此變更算作一種配置。
在大多數情況下,您不需要保證物件是不可變的。當出現這種需要時,通常凍結物件就足夠了,但是如果出現這種需要,我們還有其他選項可以進行更精細的控制。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3