我在玩镀铬控制台,注意到一些我无法理解的东西。我知道在JS中,变量是通过值复制的,对象是通过引用复制的。下面的代码工作得很好,可以输出2,并证明JS对象可以作为参考:
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 ??发布于 2013-10-18 11:33:52
我宁愿把带有对象的变量看作对象的指针(比如C指针),而不是引用。
在第三行中,您刚刚替换了objA,使其“指向”另一个对象。它不会改变任何objB“指向”的内容。
在第3行,objA现在指向{a:2},而objB仍然指向在您将其分配给objB时所指向的任何objA,在第2行,即{a:1}。
line 1: objA -> {a:1}
line 2: objA -> {a:1} <- objB
line 3: objA -> {a:2}, objB -> {a:1}发布于 2013-10-18 12:20:29
我喜欢把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写在一张新的便条上,放在冰箱上。2号码从便笺x复制到另一个便笺y上,然后放在冰箱上。y的值,并将数字3写在上面。x的值是2,粘性便笺y的值是3。这被称为按值复制,因为我们只是将便笺x的值复制到便签y上。
现在让我们以一个引用复制的例子为例。实际上,让我们以引用的副本为例:
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中的相同对象。这被称为按引用复制,因为我们只是简单地将对象的引用从便签objA复制到粘滞便笺objB。我们不是在复制实际的物体。
那么,引用复制和按价值复制之间有什么区别呢?什么事也没有。在这两种情况下,我们只是将一张便笺的值复制到另一张便笺上。
只有当两张便条包含完全相同的信息时,它们才会被认为是等价的。例如,以下内容是等价的:
var x = 2;
var y = 2;
alert(x === y); // true
var o = {a: 1};
var p = o;
alert(o === p); // true然而,以下值并不等价:
var o = {a: 1};
var p = {a: 1};
alert(o === p); // false它们不等价的原因是,o指向存储在内存位置的对象,比如x,而p指向存储在不同内存位置的对象,比如y。虽然这两个对象具有完全相同的属性,但它们实际上是两个不同的对象。
例如,任天堂的两个游戏男孩都是一样的,不管他们看上去有多相同。本着同样的精神,让我们看看最后一个例子:
var objA = {a: 1};
var objB = objA;
objA = {a: 2}; //Assigned whole object here instead property.
objB.a; //1 - Shouldn't this be 2 ??下面是上面代码中发生的情况:
{a: 1},x并在便签objA上写入地址x。x从便签objA复制到便笺objB。它们现在都指向存储在内存位置x上的同一个对象。{a: 2},y,并在objA上写入地址y。现在,objA有一个引用值y,objB有一个引用值x。它们指的是两个不同的物体。正如您所看到的,为objA分配一个新的引用值只是覆盖了旧的引用值。它不会将对象{a: 1}替换为对象{a: 2}。这在JavaScript中是不可能的。
发布于 2013-10-18 11:33:58
第一个示例的工作原理是两个变量指向的对象都是相同的。
在您的第二个示例中,没有这样做,因为您要将另一个对象分配给line #3的objA。
objA = {a: 2}; //Assigned whole object here instead property.这将使objA指向另一个对象({a:2}),而objB将指向旧对象。
https://stackoverflow.com/questions/19448646
复制相似问题