在 javascript 中,按值传递和按引用传递到底是如何工作的?

How exactly is does pass by value and pass by reference work in javascript?

提问人:ADoyle 提问时间:5/31/2022 更新时间:6/1/2022 访问量:378

问:

我一直在阅读 javascript 中按值传递与按引用传递的信息,我读到 JavaScript 总是按值传递,只有非原始类型,值是内存中的地址。但是,原始类型不也是这样吗?基元类型是否也存储在内存中,分配给它们的变量也需要指向它们的位置? 我将用这张表来尝试解释我在说什么。

变量 地址 价值
一个 0x01 10
b 0x02 10
c 0x03 [1, 2]
d 0x03 [1, 2]

当变量“b”被赋值为“a”(b=a)时,地址“a”(10)处的值被复制,并且该副本被放置在内存中的不同位置,新地址被赋给“b”?

当 d = c 时,变量 d 不是在 'c' 地址处复制值,而是被赋予与 c 相同的地址 - 它们现在都指向内存中存储数组 [1, 2] 的同一位置?

表格是准确的还是... ?

谢谢。

JavaScript 按引用传递

评论

1赞 Quentin 5/31/2022
JavaScript 规范没有描述实现应如何将数据存储在内存中。这是一个实现细节。
0赞 5/31/2022
这张表大致准确。请注意,这不是一个值,而是一个对象。从某种意义上说,这个值实际上就像 中的指针一样,但 Javascript 使这一切变得透明。[1,2]0x03c
0赞 user102008 6/12/2022
这个问题与“传递”无关,而是与赋值的语义有关。

答:

0赞 wang 6/1/2022 #1

声明变量时,JavaScript 引擎会在两个内存位置为变量分配内存:和 。stackheap

静态数据是在编译时其大小固定的数据。静态数据包括:

  • 基元值(null、undefined、boolean、number、string、symbol 和 BigInt)
  • 引用对象的引用值。

由于静态数据的大小不会改变,因此 JavaScript 引擎会为静态数据分配固定数量的内存空间,并将其存储在堆栈中。

例如,下面声明两个变量,并将其值初始化为文本字符串和数字:

let name = 'John';
let age = 25;

由于 name 和 age 是基元值,因此 JavaScript 引擎将这些变量存储在堆栈上,如下图所示:enter image description here

与堆栈不同,JavaScript 将对象(和函数)存储在堆上。 JavaScript 引擎不会为这些对象分配固定数量的内存。相反,它会根据需要分配更多空间。

以下示例定义 name、age 和 person 变量:

let name = 'John';
let age = 25;

let person = {
  name: 'John',
  age: 25,
};

enter image description here

在此图中,JavaScript 在堆栈上为三个变量 name、age 和 person 分配内存。

JavaScript 引擎在堆内存上创建一个新对象。此外,它还将堆栈内存上的 person 变量链接到堆内存上的对象。

正因为如此,我们说 person 变量是引用对象的引用。

详情请按此查看

评论

1赞 ADoyle 6/1/2022
这真的帮助我想象和理解这一切是如何工作的,您提供的链接也非常有帮助,感谢您的回答王感谢磨坊!