JavaScript - 为什么增量运算符会修改不可变字符串?

时间:2015-06-04 18:11:09

标签: javascript string immutability nan

在JavaScript中,字符串是不可变的。这意味着对它们的任何操作都会返回一个新对象。 trimreplaceslice等方法不会修改现有字符串。

但是,我在jsconsole中玩游戏并发现异常

string = "string";
string + 37;
=> "string37"
string;
=> "string"

原始字符串在这里没有改变。这是我在字符串上应用增量运算符时会发生的情况。在这里,我希望看到string返回。

string++;
=> NaN
string
=> NaN

我试图看看这是否会返回strinh,就像在其他语言中一样。

无论string++是否有效,都不应修改现有的字符串对象。然而它就是这样做的。有谁知道为什么?

2 个答案:

答案 0 :(得分:3)

++运算符的工作方式类似于:

string = string + 1;

因此,您正在重新分配该变量。 (虽然原始字符串仍然是不可变的)

如果您自己运行string = string + 1,则会发现string1会产生1。这是因为++被转换为字符串,然后被视为"追加"。 (再次,永远不要修改原始字符串

然而,string不会尝试强制任何东西,它只是尝试将一个非数字(即:1)添加到一个数字(NaN),结果是adapter.notifyDataSetChanged()

答案 1 :(得分:2)

这是一个简单的例子:

var baz = "string";
baz = 5;

当然,我们尚未通过将"string"分配给baz来修改字符串5的值。相反,我们完全取消了字符串,并将值5放在其位置。同样,您的示例不会通过将变量分配给NaN来改变任何字符串。

您希望变量string常量,但事实并非如此。此外,常量变量和不可变值是不同的东西。您尚未将不可变字符串"string"更改为NaN;您已将不可变值"string"替换为完全不同的值NaN

您的操作通过使用将不可变字符串作为操作数来创建新值。

在支持const关键字的环境中考虑一个真正的常量变量:

> const foo = 5;
> foo++
  5

现在考虑一个作为对象的常量变量:

> const bar = {};
> bar.baz = 5
> bar
  { baz: 5 }
> bar = 10;
> bar
  { baz: 5 }

在这种情况下,我们改变了值(因为值不是不可变的)但是不能改变变量包含的值。您的示例不使用常量变量,因此变量string可以自由更改其值。