可变大小的JavaScript字符串如何成为基元类型

How is the variable sized JavaScript string a primitive type?

本文关键字:何成 类型 字符串 JavaScript      更新时间:2023-09-26

据我所知,JavaScript中的(基本)string类型是一个基元类型,这意味着它的变量在堆栈上分配。

我本以为,要想在堆栈上分配一个类型,它需要有一个固定的大小——这可能适用于其他基元类型,如booleannumber等。

我认为这是错误的吗?还是其他一些内部魔法被用来在JavaScript基元类型中生成strings?


编辑:当考虑到JavaScript是松散类型的时,情况会变得更加复杂。这让我想知道任何局部变量是如何在堆栈上分配的。。。。假设在函数过程中可能分配给它的内容的大小不是固定的。

但我想(也许是简化的)答案可能是,所有局部变量都可以在堆栈上分配一个固定的最大大小。假设这是8个字节,我认为这是number类型的大小,并且应该足够大,以容纳所有其他基元类型(除了string)以及内存地址(用于为局部变量分配引用类型时)。但是,字符串肯定不能被限制为8个字节(或者任何大小)。这让我得出结论,字符串(甚至是基元类型的字符串)没有(不能)在堆栈上赋值。因此,JavaScript中的"原始类型"一词被用来表示"基本/构建块"类型,而不是必须在堆栈上分配的类型(与我在许多来源中读到的内容相矛盾,包括Nicholas Zakas的《专业JavaScript…》一书)。

有人有其他观点或指向好消息来源谈论这件事吗?

字符串既是对象也是基元。

执行时:

var s = "this is a string";

你真的这么做了:

var s = new string("this is a string");

在窗帘后面。

第一个是一个包含字符的基元数组,第二个引用该基元数组。

字符串是不可变的,这意味着它们不能更改。如果您尝试更改它(即反转它),您将创建一个新的字符串基元,对象引用将指向该基元。

在Javascript解释器中用于表示变量的存储不需要看起来像堆栈——它取决于实现。

  1. 字符串未在堆栈上分配
  2. 分配变量的位置不会区分基元和对象
  3. 字符串不是基元,它们属于"string"类

基元和类型之间的区别在于,类型有方法,您可以为它们分配新的属性:

var a = 1, b = {}, s = '';
a.foo = 1; // doesn't work, but no error either
b.foo = 1; // works
s.foo = 1; // doesn't work, but no error either
console.log(a.foo);
console.log(b.foo);
console.log(s.foo);
​

给出

undefined
1
undefined

总而言之,我不确定在JavaScript中使用"primitive"是否有意义,因为这条线是模糊的。

字符串是一个"值对象",这意味着您不能更改任何属性。例如,当您替换字符串中的字符时,您将获得一个新字符串;旧绳子不会变。