我在这里已经阅读了问题和答案:
但对我来说,为什么数字(原始类型)是不可变的还不够明确?仅仅因为他们创建了一个新的引用但没有覆盖该值?
如果在每个assignemt上创建了新的参考
var x = 5;
x = 1;
我们在以下循环中会有100次新引用吗?
while (x < 101)
{
x++;
}
效率这么高吗?我想我没看错。
答案 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的类型就像普通对象一样。更改不可变对象的属性时,将创建一个新对象,并且只能通过该新对象显示更改。好处是可以节省内存空间,只需比较它们的引用就可以快速检查对象的相等性。你得到一组行为类似于整数的类型,但你可以在其中存储更复杂的结构。