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

JavaScript 中的物件可變性

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

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]刪除
最新教學 更多>
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP將...
    程式設計 發佈於2025-06-10
  • Java數組中元素位置查找技巧
    Java數組中元素位置查找技巧
    在Java數組中檢索元素的位置 利用Java的反射API將數組轉換為列表中,允許您使用indexof方法。 (primitives)(鏈接到Mishax的解決方案) 用於排序陣列的數組此方法此方法返回元素的索引,如果發現了元素的索引,或一個負值,指示應放置元素的插入點。
    程式設計 發佈於2025-06-10
  • 表單刷新後如何防止重複提交?
    表單刷新後如何防止重複提交?
    在Web開發中預防重複提交 在表格提交後刷新頁面時,遇到重複提交的問題是常見的。要解決這個問題,請考慮以下方法: 想像一下具有這樣的代碼段,看起來像這樣的代碼段:)){ //數據庫操作... 迴聲“操作完成”; 死(); } ? > ...
    程式設計 發佈於2025-06-10
  • Python高效去除文本中HTML標籤方法
    Python高效去除文本中HTML標籤方法
    在Python中剝離HTML標籤,以獲取原始的文本表示Achieving Text-Only Extraction with Python's MLStripperTo streamline the stripping process, the Python standard librar...
    程式設計 發佈於2025-06-10
  • 圖片在Chrome中為何仍有邊框? `border: none;`無效解決方案
    圖片在Chrome中為何仍有邊框? `border: none;`無效解決方案
    在chrome 在使用Chrome and IE9中的圖像時遇到的一個頻繁的問題是圍繞圖像的持續薄薄邊框,儘管指定了圖像,儘管指定了;和“邊境:無;”在CSS中。要解決此問題,請考慮以下方法: Chrome具有忽略“ border:none; none;”的已知錯誤,風格。要解決此問題,請使用以下...
    程式設計 發佈於2025-06-10
  • Go語言如何動態發現導出包類型?
    Go語言如何動態發現導出包類型?
    與反射軟件包中的有限類型的發現能力相反,本文探索了替代方法,探索了在Runruntime。 go import( “ FMT” “去/進口商” ) func main(){ pkg,err:= incorter.default()。導入(“ time”) 如果er...
    程式設計 發佈於2025-06-10
  • 在C#中如何高效重複字符串字符用於縮進?
    在C#中如何高效重複字符串字符用於縮進?
    在基於項目的深度下固定字符串時,重複一個字符串以進行凹痕,很方便有效地有一種有效的方法來返回字符串重複指定的次數的字符串。使用指定的次數。 constructor 這將返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.W...
    程式設計 發佈於2025-06-10
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb sudo pip in...
    程式設計 發佈於2025-06-10
  • Python中何時用"try"而非"if"檢測變量值?
    Python中何時用"try"而非"if"檢測變量值?
    使用“ try“ vs.” if”來測試python 在python中的變量值,在某些情況下,您可能需要在處理之前檢查變量是否具有值。在使用“如果”或“ try”構建體之間決定。 “ if” constructs result = function() 如果結果: 對於結果: ...
    程式設計 發佈於2025-06-10
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-06-10
  • 如何在無序集合中為元組實現通用哈希功能?
    如何在無序集合中為元組實現通用哈希功能?
    在未訂購的集合中的元素要糾正此問題,一種方法是手動為特定元組類型定義哈希函數,例如: template template template 。 struct std :: hash { size_t operator()(std :: tuple const&tuple)const {...
    程式設計 發佈於2025-06-10
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-06-10
  • C++20 Consteval函數中模板參數能否依賴於函數參數?
    C++20 Consteval函數中模板參數能否依賴於函數參數?
    [ consteval函數和模板參數依賴於函數參數在C 17中,模板參數不能依賴一個函數參數,因為編譯器仍然需要對非contexexpr futcoriations contim at contexpr function進行評估。 compile time。 C 20引入恆定函數,必須在編譯時進...
    程式設計 發佈於2025-06-10
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-06-10
  • 如何在GO編譯器中自定義編譯優化?
    如何在GO編譯器中自定義編譯優化?
    在GO編譯器中自定義編譯優化 GO中的默認編譯過程遵循特定的優化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    程式設計 發佈於2025-06-10

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

Copyright© 2022 湘ICP备2022001581号-3