Javascript 字符串文字:它们是引用类型还是值类型?

Enr*_*one 5 javascript

我知道这个问题有点毫无意义,因为在 Javascript 中字符串是不可变的,所以从某种意义上说,知道它们是被建模为 值类型还是引用类型并不是那么有用。

所以,把我的问题当作好奇:Javascript 中的字符串文字是值类型还是引用类型?

因为我知道在术语方面存在很多混淆,所以我想澄清引用类型值类型的含义。

当我说引用类型时,我指的是分配给变量的值实际上是对内存中对象的引用的类型。例如,对象文字会发生这种情况:

const myObject = {foo: "bar"};
const anotherObject = myObject; // both the variables myObject and anotherObject are references to the same memory address. Only one object exists in memory
Run Code Online (Sandbox Code Playgroud)

另一方面,当我说值类型时,我指的是分配给变量的值是表示变量预期值的真实数据(而不是指向包含真实数据的内存地址的指针)的类型。例如,布尔值会发生这种情况:

const myBoolean = true;
const anotherBoolean = true; // here both of the variables contain the actual data (which is the intended boolean value of the variable). There are two distinct and independent sequences of bytes representing the two distinct and independent boolean data in memory
Run Code Online (Sandbox Code Playgroud)

为什么我不认为这是重复的

链接的问题与我的有些相关,但我专门询问如何在 Javascript 程序的内存中对字符串进行建模,而链接的问题询问为什么可以在字符串文字上调用方法,并且与以下想法更相关拳击在其答案中进行了解释。

给每位读者的重要提示:由于不可变性,这个问题实际上毫无意义

有关完整说明,请参见此处

在这里,我只报告上面链接的文章中的一些引用:

由于字符串是不可变的,我们最初的问题是没有实际意义的:没有办法判断字符串是按值传递还是按引用传递。我们可以假设,为了效率,JavaScript 被实现为通过引用传递字符串,但实际上这无关紧要,因为它对我们编写的代码没有实际影响。

再次,在文章的底部:

这个实验表明字符串是按值比较的。这可能会让一些程序员感到惊讶。在 C、C++ 和 Java 中,字符串是引用类型并通过引用进行比较。如果要比较两个字符串的实际内容,必须使用特殊的方法或函数。然而,JavaScript 是一种高级语言,它认识到当您比较字符串时,您通常希望按值比较它们。因此,尽管为了效率,JavaScript 字符串(大概)是按引用复制和传递的,但它们按值进行比较。

长话短说:实际实现可能取决于特定的 javascript 解释器(换句话说,这是一个实现细节)。出于效率的原因,将字符串建模为引用类型似乎是合理的,但它也可能取决于所使用的实际解释器。无论如何,字符串的不变性使整个讨论毫无意义,这只是一个好奇的问题

Cla*_*ity 9

如果你声明像这样的字符串

const a = 'a' 
const b = 'a'
a === b // true
Run Code Online (Sandbox Code Playgroud)

那么它们就是值类型。

然而 JS 也有一个String构造函数,所以如果你这样做:

const a = new String('a');
const b = new String('a');
a === b // false
Run Code Online (Sandbox Code Playgroud)

在这种情况下,将通过引用对它们进行比较。更多信息

  • 恕我直言,这是不正确的,因为字符串是在堆上分配的。字符串是一种特殊的引用类型,其作用类似于等于运算符中的值类型。当字符串传递给函数时,它的引用传递给函数而不是其值的副本。每次调用函数时将整个字符串值复制到该函数会降低性能。假设您有 100KB 大小的字符串。每次将变量分配给另一个变量或将其传递给函数时,JavaScript 引擎都会复制它,这是否符合逻辑? (2认同)
  • 我测试了一个小脚本并检查了开发人员工具的内存选项卡。我现在完全确定字符串是引用类型。 (2认同)