当通过引用而不是按值复制 JavaScript 值时,是否有任何经验法则

Are there any rules of thumb for when JavaScript values are copied by reference and not by value?

本文关键字:值时 JavaScript 是否 经验法则 任何 复制 引用      更新时间:2023-09-26

即使作为一个经验丰富的JS开发人员,我发现自己经常对对象的浅拷贝和深拷贝感到惊讶。

对于通过引用而不是按主要对象类型的值复制 JavaScript 值时,是否有任何经验法则?例如,我知道字符串值总是通过值而不是引用复制的。

在 JavaScript 中,所有对象都"通过引用"存储和传递。

var a = { v: 'a' }, b = { v: 'b' };
a=b;
b.v='c';

ab 将引用同一对象; a.v == 'c'b.v == 'c'.

基元数据类型(stringnumberbooleannullundefined(是不可变的;它们是按值传递的。

var a = 'a', b = 'b';
a=b;
b='c';

由于我们正在处理原语,因此a == 'b'b == 'c'.


学究们会告诉你,JavaScript不是经典意义上的按引用传递,或者它是一种"纯粹的按值传递"语言,但我认为这会使实际目的复杂化。 不,您不能直接修改传递给函数的参数,就好像它是变量一样(如果语言是真正的按引用传递,则为真(,但您也不会收到作为参数传递的对象的副本(就像如果它是真正的按值传递一样(。 对于大多数目的(从语言用户 u 的角度来看(,传递给函数的对象是引用,因为您可以修改该对象并且它会影响调用方的对象。 另请参阅此问题的精彩答案。

好的,让我解释一下你的代码:

var x, y;
x = { 'blah': 'foo' };
y = x;
x = { 'bar': 'bas' };

因此,您声明两个变量,然后将对象值分配给第一个变量:

x = { 'blah': 'foo' };

那么,这里会发生什么:

  1. 评估对象文本 - { ... } - ,这将导致创建和初始化新的本机对象。
  2. 对此对象的引用被分配给变量 x

接下来,这一行

y = x;

只是将存储在x中的引用复制到变量 y 中。现在,两个变量存储对对象的相同引用。

最后,这条线

x = { 'bar': 'bas' };

为变量 x 赋值。计算对象文本,导致创建/初始化另一个对象,并且对该对象的引用存储在x中。

然而,变量y仍然包含对第一个对象的引用。