十一 Javascript的按值传递

发布于:2025-07-11 ⋅ 阅读:(15) ⋅ 点赞:(0)

你将知道:

  • “传递” 值是什么意思
  • 什么是按值传递
  • 传递物品
  • JavaScript 中没有传递引用!


介绍

当需要在 JavaScript 中分配或简单地将一个值传递给其他标识符时,我们就会看到通常所说的 按值传递

严格来说,JavaScript 中传递值的方式只有一种,那就是复制值,这本质上就是所谓的“按值传递”。换句话说,JavaScript 实际上只支持“按值传递” 。

然而在 JavaScript 中,绝对没有办法通过引用传递数据(至少目前是这样)。

‘传递’ 是什么意思?

基本上,每当我们在 JavaScript 中将一个标识符(即变量、常量、属性等)分配给另一个标识符时,我们所做的事情就是传递标识符。传递标识符只是将其分配给另一个标识符。

例如,如果我们有一个变量 x 并将其分配给另一个变量 y ,我们会说我们将变量 x 传递给 y 。类似地,如果我们将变量 x 作为参数提供给函数 f() ,我们再次说我们正在传递变量 x 但这次是传递给函数 f()

什么是按值传递?

按值传递是指通过复制其值来传递标识符。

在按值传递中,传递的标识符中存储的值被复制 ,然后其副本存储在另一个标识符中。

因此,我们说 “按值传递” ,也就是说,我们传递存储的精确值。

var text = 'Hello';
var str = text;

text = 'Bye';

console.log(str);

那么,代码将记录值 'Hello'

首先,我们定义一个变量 text ,并将其初始化为 'Hello' 。然后,我们将 text 赋值给第二个变量 str 。完成后,我们最终修改 text ,然后输出 str 值。

现在,人们可能会认为,既然 text 已赋值给 str ,那么更改 text 也会导致 str 发生更改;但这并没有发生。这仅仅是因为 JavaScript 中的原语是按值传递的。

当我们将 text 分配给 str 时,将复制存储在 text 中的实际值 (即 'Hello' ,并将副本分配给 str

换句话说,变量 textstr 都有各自独立的 'Hello' 值;改变其中一个不会明显改变另一个。

上面的代码从技术上讲等同于下面的代码:

var str = 'Hello'; // own value
var text = 'Hello'; // own value

text = 'Bye';

console.log(str);

JavaScript 数据类型不只有原始类型,对吧?我们还有对象。现在,对象传递也是按值传递的。

ha?

在 JavaScript 中,对象通过其引用 存储在标识符中 而不是通过其实际值。

引用可以被认为是指向存储对象位置的内存地址。

由于 JavaScript 中的对象通过其引用存储在标识符内,因此当传递该对象时,实际传递的是该引用。
 

对象是真实的数据;引用是对象在程序中的表示方式

再次强调,需要特别注意的是,对象仍然像 JavaScript 中的原语一样传递,即按值传递;对象唯一的不同之处在于它们的存储方式,即通过引用。

var obj = { x: 10 };
var obj2 = obj;

obj.x = 20;

console.log(obj2.x);  // 20 

我们首先定义一个变量 obj ,其值为 { x: 10 } 然后定义另一个变量 obj2 ,并将其初始化为 obj

接下来,我们改变 obj 的属性 x ,然后记录 obj2 的相同属性。

obj.xobj2 中可见,仅仅是因为 objobj2 都引用内存中 obj 同一个对象 。obj 和 obj2保存单独的对象 - 它们保存完全相同的对象。

JavaScript 中对象是如何存储的

这是我们的 obj 变量。它包含一个指向内存中对象 { x: 10 } 的值(箭头所示)。这个值就是我们所说的引用。

当我们将 obj 赋值给另一个变量 obj2 时,会发生以下情况:

在 JavaScript 中将对象分配给另一个标识符

obj 中存储的值(引用)仅仅被复制到 obj2 中。因此, obj2 指向(箭头所示) obj 指向的同一个对象 { x: 10 }

如果我们现在继续更改 obj 的属性,就像我们在上面的代码中通过更新属性 x 所做的那样,那么该更改在 obj2 中也会可见。

重申一下:

当我们将 obj 分配给 obj2 时, obj 中存储的实际值 (即引用 )被复制,并将该副本分配给 obj2 。 实际也还是值传递,只是这个值是引用。

从今以后,如果我们改变存储在 obj (或 obj2 )中的对象,这些变化显然也会在 obj2 (或 obj )中可见,因为它们都包含完全相同的对象。

(牢记上面的图)
 


JavaScript 中没有传递引用!

不能真正在 JavaScript 中通过其引用(在内存中)传递标识符,并期望其他代码能够控制该标识符中存储的内容。

事实上,很容易确认传统意义上的 JavaScript 不支持传递引用。

以上面部分的代码为例,如果我们将任何值重新分配给 objobj2 本身,另一个变量不会发生神奇的变化。

var obj = { x: 10 };
var obj2 = obj; // This is just pass-by-value.

obj = 20;

console.log(obj2);

{ x: 10 }

这里的一切与之前相同,只是现在变量 obj 自身发生了改变(而不是像之前那样改变其属性 x )。然后,直接输出 obj ,而不是输出 obj.x

因为 JavaScript 中没有真正意义上的按引用传递,所以我们在为 obj 分配值时, obj2 不会改变 - 它会继续保留 { x: 10 }

这纯粹是因为没有任何东西将两个变量 objobj2 联系在一起。

简单来说就是,本来他俩的值都是引用,比如 16 位一个引用地址,指向了内存中的{x: 10},所以,当 xxx.x 的时候,才会影响这两个对象,但实际他俩是两个变量,当 obj = 20 的时候, 那就是一个原语,最基础的值 20。那么得到的结果当然就是 obj = 20 , obj2 = {x:10}


网站公告

今日签到

点亮在社区的每一天
去签到