簡體   English   中英

理解 Javascript 不可變變量

[英]Understanding Javascript immutable variable

我試圖了解 Javascript 不可變變量的含義。 如果我能做到:

var x = "astring";
x = "str";
console.log(x); //logs str` , then why it is immutable?

我能想到的唯一答案(從 CI 的一點點知道)是 var x 是指向值為“astring”的內存塊的指針,在第二條語句之后,它指向另一個值為“str”的塊。 是這樣嗎?

還有一個額外的問題:我對 Javascript 的值類型感到困惑。 引擎蓋下的所有變量都是對象嗎? 偶數和字符串?

是不可變的; 變量不是; 他們擁有對其(原始)值的引用。

字符串,數字和布爾值這三種原始類型具有對應的類型,其實例是對象: 字符串,數字,布爾值
它們有時稱為包裝器類型

以下是原始值:

  • 字符串:“ hello”
  • 數字:6、3.14(JavaScript中的所有數字均為浮點數)
  • 布爾值:true,false
  • null:通常顯式分配
  • 未定義:通常為默認值(自動分配)

所有其他值都是對象,包括基元的包裝。

所以:

  • 默認情況下對象是可變的
  • 對象具有唯一標識,並通過引用進行比較
  • 變量保存對對象的引用
  • 基元是不可變的
  • 比較基元的價值,他們沒有個人身份

您可能會發現JavaScript原語的秘密生活是一個很好的解釋。

另外,在ES6中,有一個新的const關鍵字,它創建一個只讀的命名常量,該常量不能通過賦值來更改值,也不能在腳本運行時重新聲明。

希望這可以幫助!

首先,在C中,“字符串是最后一個elem ='\\ 0'的字符數組”。 它們是可變的。
如果像這樣在C中聲明和初始化字符串:

char str[] = "Foo";

您基本上要做的是保留4個字節(可能是8位字節,如果這對您造成傷害,請不要介意)。 單詞str用作此數組的第一個元素的指針。 因此,如果您這樣做:

str[0] or *(str) = 'G'

那么它將改變該地址的值,而不是創建新的數組。 您可以通過打印出str的地址來進行驗證。 在兩種情況下都是一樣的。

現在,在JavaScript的情況下,字符串是原始類型。 對字符串的所有操作都是通過值而不是引用來完成的。 因此,這樣做將產生真實的效果。

var str1 = "foo";
var str2 = "foo";
str1 === str2; => true

字符串的初始化要求緩沖區適合“ foo”,並將名稱str1綁定到該緩沖區。 使它們不可變的原因是您無法更改該緩沖區。 因此,您不能執行以下操作:

str1[0] = 'G'

在非嚴格模式下執行此命令不會產生警告或錯誤,但是不會更改str1。 您可以通過以下方式進行驗證

console.log(str1) => "foo"

但是,如果您這樣做:

str1 = "goo"

您實際上正在做的是要一個新的緩沖區以適合“ goo”並將標識符str1綁定到該緩沖區。 包含“ foo”的舊緩沖區沒有變化。

那么,“ foo”會怎樣?

Java Script具有自動垃圾回收器。 當它看到不再可以由任何標識符或...引用的某些內存塊時,則認為該內存可用。

布爾也一樣。 現在,關於包裝對象! 每當您嘗試訪問像這樣的字符串上的屬性時:

str1.length;

JavaScript會使用String類創建一個新對象並在string上調用方法。 一旦函數調用返回,對象就會被銷毀。 以下代碼進一步解釋了它:

var str = "nature"; 
str.does = "nurtures"; //defining a new property; 
console.log(str.does) => undefined

因為對象已被破壞。 嘗試這個!

var str = new String("Nature");
str.does = "nurtures";
console.log(str) =>  ??

這個str確實是一個對象...

結論:在C中,在單個作用域中,變量名用作指針。 因此,int,float,string都是可變的。 但是在Java Script中,原始類型變量名稱用作值,而不是引用

參考:C ++入門指南,Java腳本權威指南,Stephen Kochan的C

你是對的。 字符串(和數字)在Java腳本(和許多其他語言)中是不可變的。 變量是對其的引用。 當“更改變量的值”時,您更改的是變量引用的字符串(或其他內容),而不是值本身。

我認為許多新程序員都認為不變性意味着原始值不能通過重新分配來更改。

 var str = "testing"; var str = "testing,testing"; console.log(str); // testing, testing 

 var fruits = ["apple", "banana", "orange"]; fruits[0] = "mango"; console.log(fruits); //["mango", "banana", "orange"] 

與可變類型和不可變類型相關聯的值可以通過重新分配進行更改,如上述帶有字符串和數組的示例所示。 但是,這些數據類型具有關聯的函數(方法),這些函數用於處理屬於每種數據類型的值。 在這里可以看到可變性/不變性。 由於數組是可變的,因此使用數組方法進行的任何操作都會直接影響數組。 例如,

 var fruits = ["mango","banana", "orange"]; fruits.pop(); console.log(fruits) //["mango", "banana"] The array.pop() method deleted "orange" from the original fruits array. But with strings for example, var name = "Donald Trump"; name.replace("Donald", "President"); console.log(name)//Donald Trump the original string remains intact! 

不變性不允許通過字符串方法更改原始字符串。 相反,如果將方法操作分配給變量,則該方法將產生一個新字符串,如下所示:

 var name = "Donald Trump"; var newName = name.replace("Donald", "President"); console.log(newName);//President Trump 

在這里先了解一下,

let firstString = "Tap";

console.log(firstString);  //Output: Tap 

firstString[0] = "N";

console.log(firstString)   //Output: Tap

這就是我們可以看到不可變效果的地方

這個定義中的不變性是歷史性的。 它附屬於可以用其他編程語言完成的工作。

我認為這是首先要理解的。 對於只使用過 JavaScript 的程序員來說,這個問題可能看起來很荒謬或不必要的迂腐。 將原語描述為不可變就像將冰淇淋描述為不能跳躍一樣。 為什么我覺得可以? 只有與其他歷史編程語言相比,在處理原始類型時才會明顯缺乏可變性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM