不可变是什么意思?

IT技术 javascript variables immutability
2021-03-03 16:33:08

如果一个字符串是不可变的,这是否意味着......(让我们假设 JavaScript)

var str = 'foo';

alert(str.substr(1)); // oo

alert(str); // foo

这是否意味着,在字符串上调用方法时,它会返回修改后的字符串,但不会更改初始字符串?

如果字符串是可变的,这是否意味着第二个alert()也会返回oo

6个回答

这意味着一旦你实例化了对象,你就不能改变它的属性。在您的第一个警报中,您没有更改 foo。您正在创建一个新字符串。这就是为什么在您的第二个警报中它会显示“foo”而不是 oo。

这是否意味着,在字符串上调用方法时,它会返回修改后的字符串,但不会更改初始字符串?

是的。字符串一旦创建就无法更改。现在这并不意味着您不能为str变量分配一个新的字符串对象您只是无法更改 str 引用的当前对象。

如果字符串是可变的,这是否意味着第二个 alert() 也会返回 oo ?

从技术上讲,不会,因为 substring 方法返回一个新字符串。使对象可变,不会改变方法。使其可变意味着从技术上讲,您可以使子字符串更改原始字符串而不是创建新字符串。

如果修改和分配相同的字符串,将更新字符串 var str = 'foo'; str = str.substr(1)); // oo 警报(str); // 哦
2021-04-30 16:33:08
下面的代码呢。字符串值现在已更改。var name = "Santosh"; console.log(name.substr(0,2)); var name = "kumar" console.log(name); 它如何仍然不可变
2021-05-06 16:33:08

在较低级别上,不变性意味着存储字符串的内存不会被修改。创建字符串后"foo",会分配一些内存来存储该值"foo"这个记忆不会被改变。如果您修改字符串,例如,substr(1)将创建一个新字符串并分配内存的不同部分,该部分将存储"oo". 现在您在内存中有两个字符串,"foo"并且"oo". 即使你"foo"不再使用它,它也会一直存在,直到它被垃圾收集。

字符串操作相对昂贵的原因之一。

@Hacker 不。您已将一个新字符串分配给指向内存中新位置的变量。
2021-04-24 16:33:08
数字也是不可变的。
2021-04-30 16:33:08
这个答案比公认的答案更合乎逻辑。
2021-05-11 16:33:08
2015年你好!!“在较低级别上,不变性意味着存储字符串的内存不会被修改。” --- 这太严格了,听起来不正确。不变性仅与用户空间有关,一旦保留语言规范不变量,虚拟内存可能会根据内存分配器的喜好进行更改。
2021-05-16 16:33:08
但我可以像 var str = 'foo'; 我可以通过 str = 'bar' 进行修改。str 值以这种方式修改了吗?
2021-05-20 16:33:08

不可变意味着不能改变或修改。

因此,当您为字符串赋值时,该值是从头开始创建的,而不是被替换。因此,每次将新值分配给同一个字符串时,都会创建一个副本。所以实际上,你永远不会改变原始值。

我不确定 JavaScript,但在 Java 中,字符串通过“字符串常量池”向不变性迈出了额外的一步。字符串可以用字符串文字 ( "foo") 或String类构造函数构造。使用字符串字面量构造的字符串是字符串常量池的一部分,并且相同的字符串字面量将始终来自池中的相同内存地址。

例子:

    String lit1 = "foo";
    String lit2 = "foo";
    String cons = new String("foo");

    System.out.println(lit1 == lit2);      // true
    System.out.println(lit1 == cons);      // false

    System.out.println(lit1.equals(cons)); // true

在上面,lit1lit2都是使用相同的字符串字面量构造的,因此它们指向相同的内存地址;lit1 == lit2结果为true,因为它们是完全相同的对象。

但是,cons是使用类构造函数构造的。尽管参数是同一个字符串常量,但构造函数为 分配了新内存,尽管包含相同的数据,但这cons意味着conslit1和 的对象lit2不同。

当然,由于三个字符串都包含相同的字符数据,使用该equals方法会返回true。

(当然,两种类型的字符串构造都是不可变的)

可变性的教科书定义可能会发生变化或变更。在编程中,我们使用这个词来表示其状态可以随时间改变的对象。不可变值恰恰相反——它被创建后,就永远不会改变。

如果这看起来很奇怪,请允许我提醒您,我们一直使用的许多值实际上是不可变的。

var statement = "I am an immutable value";
var otherStr = statement.slice(8, 17);

我想没有人会惊讶地发现第二行不会改变语句中的字符串。事实上,没有字符串方法改变它们操作的字符串,它们都返回新的字符串。原因是字符串是不可变的——它们不能改变,我们只能创建新的字符串。

字符串并不是 JavaScript 中唯一的不可变值。数字也是不可变的。你能想象这样一个环境,其中计算表达式 2 + 3 会改变数字 2 的含义吗?这听起来很荒谬,但我们一直在用我们的对象和数组来做这件事。