JavaScript 中的引用传递 vs. 值传递

2025-06-08

JavaScript 中的引用传递 vs. 值传递

我认为理解内存以及声明变量时发生的情况非常重要。计算机内存对于人类来说可能是一个令人困惑且抽象的概念,所以我认为理解它的最佳方式是通过类比,我将在解释这一点时使用这个类比。

想象一下,你的计算机内存就像一个仓库。仓库里有一些存储箱,用于存放一箱箱的数据。声明一个变量后,你需要将一个箱子运送到仓库,然后将其存放在一个存储箱中,直到你以后需要它为止。

JavaScript 中的原始数据类型是按值传递的。如果您不确定这七种原始数据类型是什么,没关系。我建议您停下来读读这篇文章,了解一下。您可能在学习的过程中都见过它们,但了解它们之间的区别会有所帮助。MDN :JavaScript - 数据结构

假设你将一个变量设置为等于另一个变量。例如:

let box1 = 'sugar'
let box2 = box1
Enter fullscreen mode Exit fullscreen mode

让我们来分解一下……在我们众所周知的仓库里,一名工人走到箱子box1所在的位置,检查箱子,然后使用 JavaScript 魔法创建一个完全相同的副本。然后,工人将副本搬走,并将其存放在新的箱子中box2

您会看到,box1已被复制,并且box2两者都有'sugar“。”

那么,如果我们改变其中一个值会怎样?

box2 = 'brown sugar'

console.log(box1) // returns 'sugar'
console.log(box2) // returns 'brown sugar'
Enter fullscreen mode Exit fullscreen mode

它们不再相同了,不过没关系。只是传递了box2创建时的原始值,它们彼此之间没有任何关联,因此不会相互影响。

JavaScript 中的对象使用引用传递。我们使用的 JavaScript 中的大多数结构都是对象,所以我认为理解它的工作原理非常重要。对象{}由键值对、数组和函数等组成。你可能听过“JavaScript 中的一切都是对象”这句话。这话确实有道理!

const box3 = {
  contents: "salt"
}

const box4 = box3
Enter fullscreen mode Exit fullscreen mode

在这个例子中,我们的小小工人识别出这box3是一个对象。于是他草草地记下了它在仓库中的位置。然后,它快速跑到一个打开的容器旁box4,把纸贴在架子上,标明了容器的位置box3和里面的内容。

这就是引用传递。有时,我们创建或拉取到应用中的对象可能非常庞大,包含数百甚至数千个键值对。每次都进行克隆会非常浪费资源,而且会降低计算机的性能。

所以,它只是引用而已。有时这可能会产生无法预料的后果。

box4.contents = "pepper"

console.log(box3.contents) //returns "pepper"
console.log(box4.contents) //returns "pepper"
Enter fullscreen mode Exit fullscreen mode

等等!我们不是故意的。为什么会这样?

因为box4不包含自身的值,它包含对 的引用box3。通过更新 的contains属性box4,我们实际上是在告诉它更新box3.contains

这正是差异给我们带来麻烦的地方。那么,问题来了,我们如何克隆box3,而不是传递引用呢?

好吧,ES6 为我们提供了一种非常干净且好用的方法来实现这一点,即扩展运算符。

box4 = { ...box3 }
Enter fullscreen mode Exit fullscreen mode

如果愿意,您还可以使用可靠的旧克隆方法。

box4 = Object.assign({}, box3)
Enter fullscreen mode Exit fullscreen mode

请注意,这只是关于这些概念工作原理的一个非常基础的入门介绍。我希望我的例子和仓库类比能帮助你们更好地理解它们之间的区别,而不仅仅是阅读定义。不妨尝试一下,做个实验。此外,请深入挖掘,因为它对于在应用程序中处理数据非常重要。

我保证,在某个时刻,你会与它相遇或碰到它。

编辑:我从一个非常有信息量的评论中发现,这比第一次出现的要微妙一些,有关更多信息,请查看此帖子:https://dev.to/xpbytes/javascript-ruby-and-c-are-not-call-by-reference-23f7

鏂囩珷鏉ユ簮锛�https://dev.to/bbarbour/passed-by-reference-vs-value-in-javascript-2fna
PREV
哇!Next.js 继续令人印象深刻
NEXT
FreeCodeCamp 认证有分量吗?