Javascript JS对象按值复制与按引用复制

Javascript JS对象按值复制与按引用复制,javascript,Javascript,我在玩chrome控制台时,注意到一些我无法理解的东西。我知道在JS中,变量是按值复制的,对象是按引用复制的。下面的代码工作正常,输出2,证明JS对象可以作为参考: var objA = {a: 1}; var objB = objA; objA.a = 2; objB.a; // 2 var objA = {a: 1}; var objB = objA; objA.a = 2; objB.a; // 2 然而,这段代码并没有正常工作。我希望objB.a输出2,但它给出了1。为什么? va

我在玩chrome控制台时,注意到一些我无法理解的东西。我知道在JS中,变量是按值复制的,对象是按引用复制的。下面的代码工作正常,输出2,证明JS对象可以作为参考:

var objA = {a: 1};
var objB = objA;
objA.a = 2; 
objB.a; // 2
var objA = {a: 1};
var objB = objA;
objA.a = 2;
objB.a; // 2
然而,这段代码并没有正常工作。我希望objB.a输出
2
,但它给出了
1
。为什么?

var objA = {a: 1};
var objB = objA;
objA = {a: 2};  //Assigned whole object here instead property.
objB.a; //1 - Shouldn't this be 2 ??

我宁愿把带有对象的变量看作指向对象的指针(比如C指针),而不是引用

在第三行中,您刚刚替换了
objA
,使其“指向”另一个对象。它不会改变任何
objB
的“指向”

在第3行,
objA
现在指向
{a:2}
,而
objB
仍然指向您在第2行将其分配给
objB
时所指向的任何东西,即
{a:1}

line 1: objA -> {a:1}
line 2: objA -> {a:1} <- objB
line 3: objA -> {a:2}, objB -> {a:1}
第1行:objA->{a:1}
第2行:objA->{a:1}{a:2},objB->{a:1}

您的第一个示例的工作原理是两个变量指向的对象相同

在第二个示例中,没有,因为您正在将另一个对象分配给
objA
行#3

objA = {a: 2};  //Assigned whole object here instead property.

这将使
objA
指向另一个对象(
{a:2}
),而
objB
将指向旧对象。

objB在您的情况下不是指向变量objA,而是指向变量objA所指向的对象,因此,更改对象属性与更改变量点的位置不同

javascript中的变量是通过值传递的。对于对象来说,这没有什么不同。变量不是指向对象的指针,与用C++表示的方式相同。它只包含对指针的引用,该指针只能由javascript本身访问。所以当你这样做的时候:

objA = objB
只能将引用指针复制到内存中的对象

我在玩chrome控制台时,注意到一些我无法理解的东西。我知道在JS中,变量是按值复制的,对象是按引用复制的

没有。也没有“按值复制”或“按引用复制”,只有“复制”

变量的值总是引用某个对象。对象可以是
object
类型,如
{}
,也可以是Number类型,如
5
,或任何其他类型

赋值和函数调用从不复制对象在Javascript中,它只将相同的值绑定到另一个变量:

var a = {},  b = 5;
var a1 = a,  b1 = b;
// variables a and a1 refer to the same object, {}
// variables b and b2 refer to the same object, 5

a['x'] = 10; // the object referred to by a and a1 is modified
a = {'x': 10} // now a refers to a new object and a1 is unaffected

b += 10; // b and b1 now point to a different objects, 15 and 5

function foo(x) {
    ...
}
foo(a); // x inside foo is the same object, {}
foo(b); // x inside foo is the same object, 5
复制对象必须由您完成,对象不会被神奇地复制


复制
对象
s是有意义的,因为可以修改
对象
。然而,复制数字或字符串是没有意义的——您只关心变量的值引用了
1234
,而不关心“哪个特定的1234”。(它们没有“标识”。

我喜欢将JavaScript变量视为。便条是你放在冰箱上的小纸条。你可以在便条上写什么?你可以写一些小的信息

现在JavaScript中有两种类型的信息——原语值和引用值。基本值是可以直接写在便笺上的小块信息。这些措施包括:

  • 布尔人
  • 数字
  • 空的
  • 未定义
  • 另一方面,参考值是大量的信息,您无法在小便笺上书写。那么,如何在便笺中存储参考值呢

    你没有

    引用值(如数组、对象和函数)写在一张更大的纸上,只有对它们的引用才会写在便笺上。例如,我妻子可能会写道:

    亲爱的,食品清单在你的键盘下

    这里的杂货清单是一个数组(即大量信息)。因为我们不能把它写在一张小的便笺上,所以我们只需要把它写在一张更大的纸上,然后做一张便笺,告诉我们在哪里可以找到它。在节目方面:

    var groceryList = ["1 apple", "2 bananas", "3 loaves of bread"];
    
    在这里,实际的购物清单存储在内存中的某个地方,只有购物清单的地址存储在变量
    groceryList


    那么当我们把一个变量分配给另一个变量时会发生什么呢?让我们首先以一个基本值为例:

    var x = 2;
    var y = x;
    alert(y);  // 2
    y = 3;
    alert(x);  // 2
    
    这就是正在发生的事情:

  • 我们把数字
    2
    写在一张新的便签上,然后放在冰箱上
  • 我们从便笺
    x
    中将数字
    2
    复制到另一张便笺
    y
    上,然后放在冰箱上
  • 我们擦除了便笺
    y
    的值,并将数字
    3
    写在上面
  • 现在,便笺
    x
    的值为
    2
    ,便笺
    y
    的值为
    3
  • 这称为按值复制,因为我们只是将便笺
    x
    的值复制到便笺
    y

    现在让我们以引用复制为例。事实上,让我们以引用复制为例:

    var objA = {a: 1};
    var objB = objA;
    objA.a = 2; 
    objB.a; // 2
    
    var objA = {a: 1};
    var objB = objA;
    objA.a = 2;
    objB.a; // 2
    
    下面是您的示例中发生的情况:

  • 我们在内存中的某个地方创建一个对象
    {a:1}
    ,并将该对象的地址写在便笺
    objA
    上。为了简单起见,我们把这个地址称为
    x
  • 我们将地址
    x
    从便笺
    objA
    复制到另一张便笺
    objB
    。现在
    objA
    objB
    都引用了存储在内存位置
    x
    的相同对象
    {a:1}
  • 因此,当我们更改
    objA.a
    的值时,相同的更改会反映在
    objB.a
    上,因为
    objA
    objB
    都引用存储在内存位置
    x
    的相同对象
  • 这称为引用复制,因为我们只是复制ref
    var objA = {a: 1};
    var objB = objA;
    objA = {a: 2};  //Assigned whole object here instead property.
    objB.a; //1 - Shouldn't this be 2 ??