2017-09-24 68 views
4

我已閱讀問題和答案在這裏:爲什麼數字在Javascript中是不可變的?

javascript numbers- immutable

但是這還不夠清楚,我爲什麼數(基本型)是不可改變的?僅僅因爲他們創造了一個新的參考但不覆蓋價值?

如果每個assignemt創建一個新的參考

var x = 5; 
x = 1; 

我們將有100倍,在下面的循環一個新的參考?

while (x < 101) 
{ 
    x++; 
} 

這樣高效嗎?我想我看不到正確的。

+5

如果數字5是可變的,意味着什麼? – Pointy

+0

閱讀你所關聯問題的答案:數字本身是不可變的(或者你可以說常量)。變量x是對數字/常量的引用。它還表示,在所有的編程語言中它都是一樣的。否則,你可以刪除/覆蓋數字,並搞亂語言可以完成的整個數學計算。對? –

+0

嗯,但如果這個數字有點常數,爲什麼我們可以重新確定它們的值? x = 5,則x = 1。 – Jamo

回答

1

數字是不可變的,因爲它們對於它們是不可變的是有意義的:數字5是數字5,沒有修改對象本身的意義。

當你做這樣的事情:

let x = 5; 

你有對象5和可變x它引用的對象5。如果你再改x

x = 4; 

你是不是改變對象5:你正在改變是什麼變量x指向。

在你while例子有各種數值常量012...和可變x:在每次迭代中,x++改變數值常數其中可變x指向。

類似的推理可以應用到很多語言,不但爲Javascript:其實,在許多語言中的數字和常字符串是不可變對象,並按照類似的規則


編輯:正如在評論中指出,在Javascript中的數字是原始值而不是對象(即使它們可以被包裝在類Number的對象中)。因此,實際上並沒有改變x所指向的引用,因爲不涉及任何對象:您正在直接更新原始值。菲利克斯克林的答案比這更充分。

+0

好的,如果我不更改objet 5並且只是變量x指向的內容,那麼在爲x重新賦值不同值之後,對象5會發生什麼? – Jamo

+0

@jamo:根據分配的位置,它將在離開當前執行環境時自動釋放,或者如果沒有其他引用,它將被垃圾回收。 –

+1

5不是一個對象。這是一個原始價值。 x不會持有對象5的引用.x將把數字5保存爲x的值。 –

-1

原始值與參考:

在布爾型,未定義,爲null,數字,符號,字符串的JavaScript的值是原始的。當您將它們分配給變量或將它們作爲參數傳遞給函數時,它們總是被複制。相反,對象有兩個部分:對象(它是數據)存儲在一塊內存中,分配給變量的是指向該對象的引用。對象本身不會在賦值時被複制。

因爲當你將它們分配給一個變量是不可能改變了許多,看到通過一些其他變量的變化而無需實際分配一個新的價值,該變量的數值總是被複制。 相比之下,當您更改對象上的字段時,指向該對象的所有變量都會看到該更改。

讓我們看一些例子:

var a = 1; 
var b = a; //This creates a new copy of value 1 
console.log(a, b); // 1 1 
a = 2; 
console.log(a, b); // 2 1 


var obj_a = {attr: 1}; 
var obj_b = obj_a; //This makes a new reference to the same object. 
console.log(obj_a, obj_b); // {'attr': 1} {'attr': 1} 
obj_b.attr = 2; 
console.log(obj_a, obj_b); // {'attr': 2} {'attr': 2} 

不可變對象:immutable.js

圖書館像immutable.js提供結合了原始類型和對象的屬性類型:從immutable.js類型的行爲作爲普通的物體,只要你不改變它們。當您更改不可變對象的屬性時,將創建一個新對象,並且更改僅通過該新對象可見。好處是您可以節省內存空間,並且只需比較其參考即可快速檢查對象的平等性。您會得到一組類似整數的類型,但您可以在其中存儲更復雜的結構。

+1

通過引用傳遞並使用對象的引用是**不是**相同的東西。 JavaScript是通過值傳遞的,而對於對象而言,該值是引用。你很懷疑**數值**是如何用變量和參數評估的方式表示的。這是兩回事。 –

+0

這是不正確的說,字符串總是按值傳遞,因此複製。字符串總是被引用傳遞。 –

+0

@MarcinMalinowski:看到我以前的評論。 JavaScript是通過價值傳遞的,這個價值可能是一個參考。關於不可變值的好處是它們可能被複制或者可能被引用。實現可以做任何想要的事情。 –

0

突變狀態的變化而數字(基本類型)是純態的對象。對這種「對象」狀態的任何突變實際上都是一個新數字。數字本身就像計算機內存單元中位的變化的標識符。

因此數字不可變。與顏色或字符相同。

還值得claryfining一個新號碼會按觀測同一存儲單元的舊對於任何給定的變量。實際上取代了舊的。因此沒有任何性能受到影響。

+0

「純態對象」是什麼意思? – Jamo

+0

如果試圖將原始值描述爲對象不具有任何方法的對象,並且在表達式中使用對象本身時將其評估爲其狀態作爲單個值。 –

3

我說實話不太清楚你期待什麼樣的回答,因爲我不太明白你的困惑。但在這裏我們去:

我們會在下一個循環中有100次新的參考嗎?

變量是值只是容器。在低級別,變量基本上就是存儲器地址或寄存器的標籤。例如。變量x可能指向註冊R1

x++只會將存儲在該寄存器中的數字遞增1。讓我們假設我們的寄存器是這樣的:

R1: 5 

遞增它後,它可以是一個單一的操作,如ADD R1 1,我們會得到

R1: 6 

即我們簡單地用新的值覆蓋了以前的值。我們多次這樣做。


是不是有效?我想我看不到正確的。

將數字遞增1就像獲得的操作一樣簡單。

當然,你可以在更高層次上實現可變數字,但它肯定不會使事情變得更高效或更簡單。

可變性對於「單值」值沒有多大意義,因爲變異這樣的值基本上意味着用一個不同的值替換它。

對於由其他值組成的值(如列表和詞典),其中一部分發生更改而另一部分保持不變,可變性更有意義。

此外,只有當語言有引用類型數據類型時,可變性纔有意義。我的意思是說,多個變量可以保存對數據類型相同值的引用。對象是引用類型在JavaScript中,它允許你這樣做:

var a = {foo: 42}; 
 
var b = a; 
 
b.foo = 21; 
 
console.log(a);

如果數據類型是引用類型的不是,所謂價值型,(其原始值是在JavaScript),那麼可變性並不重要,因爲它與不變性是無法區分的。有一個可變的,價值型數量考慮以下假設的情景:

var a = MutableNumber(42); 
var b = a; // creates a copy of MutableNumber(42) because it's a value type 
a.add(1); 
console.log(a, b); // would log 43, 42 

在這種情況下,不可能兩個變量指向同一個可變的數值,a.add(1)是到a分配一個新的價值沒有區別(即a = a + 1)。

+0

這是一個很好的答案 –

+0

所以,我們可以說數字是不可變的,因爲每個變量(容器)都有不同的參考?該號碼不能被引用修改。 – Jamo

相關問題