为什么数字在Javascript中是不可变的?

时间:2017-09-24 16:33:42

标签: javascript immutability

我在这里已经阅读了问题和答案:

javascript numbers- immutable

但对我来说,为什么数字(原始类型)是不可变的还不够明确?仅仅因为他们创建了一个新的引用但没有覆盖该值?

如果在每个assignemt上创建了新的参考

var x = 5;
x = 1;

我们在以下循环中会有100次新引用吗?

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

效率这么高吗?我想我没看错。

5 个答案:

答案 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);

如果数据类型不是引用类型(称为value-type)(原始值在JavaScript中),那么可变性无关紧要,因为它与immutability无法区分。考虑以下具有可变值值类型的假设场景:

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)。< / p>

答案 1 :(得分:0)

变异是状态的变化,而数字(原始类型)是纯状态对象。对这种“对象”状态的任何突变实际上都是一个新数字。数字本身就像计算机存储器单元中的位变化的标识符。

因此数字不可变。与颜色或字符相同。

对于任何给定变量,新数字将与旧存储单元相同,这也是值得进行的。实际上更换旧的。因此,没有任何性能损失。

答案 2 :(得分:0)

我不完全理解这一点,

var a=12;
a=45;

我们可以从;

推断

1。首先,解释器分配一块内存并将12定位到该区域。 实际上(a)是此存储区的标签。 2.than,解释器分配一个新的存储单元并将45定位到该区域。 最后,(a)与此新存储单元相关联。包含12个内存的存储单元被垃圾回收器破坏了。

答案 3 :(得分:0)

我能理解您的问题,问题是,在while循环内,每次x指向新值时,而旧值将准备好进行垃圾回收,因此内存仍然可用。

阅读此书可以更好地理解: https://developer.mozilla.org/en-US/docs/Glossary/Mutable

关于可变性,您的理解是正确的,变量引用了新值,旧值未更改,因此原始值是不变的。

引用:https://developer.mozilla.org/en-US/docs/Glossary/Primitive

答案 4 :(得分:-1)

原始值与参考值:

在boolean类型的JavaScript值中,undefined,null,number,symbol,string是原始的。将它们分配给变量或将它们作为参数传递给函数时,它们总是被复制。 相比之下,对象有两个部分:对象(它的数据)存储在一块内存中,你赋给变量的是指向该对象的引用。对象本身不会在赋值时复制。

因为在将数字分配给变量时始终会复制数字,所以无法更改数字并通过其他变量查看更改,而无需为该变量实际分配新值。 相反,当您更改对象上的字段时,指向该对象的所有变量都将看到该更改。

让我们看一些例子:

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的类型就像普通对象一样。更改不可变对象的属性时,将创建一个新对象,并且只能通过该新对象显示更改。好处是可以节省内存空间,只需比较它们的引用就可以快速检查对象的相等性。你得到一组行为类似于整数的类型,但你可以在其中存储更复杂的结构。