删除原始对象,同时在JavaScript中保留原始对象的副本

时间:2014-12-12 15:46:39

标签: javascript javascript-objects

我测试了JavaScript对象在Chrome控制台中的行为方式。假设这可以在任何地方使用是否安全? :

a = new Object()
>> Object {}
b = a
>> Object {}
a.boo = "Yiss!"
>> "Yiss!"
b
>> Object {boo: "Yiss!"}
a = new Object()
>> Object {}
b
>> Object {boo: "Yiss!"}
a = b
>> Object {boo: "Yiss!"}
delete a.boo
>> true
b
>> Object {}
a
>> Object {}
delete a
>> true
a
>> Uncaught ReferenceError: a is not defined
b
>> Object {}

TL; DR

我只想清楚以下陈述是否属实: 在该对象的所有副本上都可以对对象的多个副本中的一个进行修改。如果副本或原件被新对象删除或替换,则不会影响其他副本。

3 个答案:

答案 0 :(得分:4)

delete所做的就是从对象中删除属性。它实际上并没有对属性的做任何事情。

此处的

ab相当于window.awindow.b,因为它们是全局的,window是全局对象。因此,delete a等同于delete window.a,它只会从a对象中删除window属性。

由于JavaScript中的变量不存储对象,而是对象的引用,delete a所做的就是删除包含的引用的变量> b继续引用的同一对象。

所以,你的问题本身是有缺陷的,因为它是基于对JavaScript中对象语义的错误理解:

  

如果副本或原件被新对象删除或替换,则不会影响其他副本。

没有这样的"副本"或者#34;原创"在这种背景下。该对象根本没有被复制。您只需要一个由多个变量引用的对象。并且,进一步地,没有明确"删除对象的概念"在JavaScript中。

答案 1 :(得分:1)

此行为完全正常,应该适用于所有JavaScript环境。让我们一步一步地完成它。

创建一个新对象并将其存储在a

a = new Object()
>> Object {}

b引用b所做的同一个对象:

b = a
>> Object {}

(你似乎认为这会以某种方式“复制”对象。这是不正确的:到目前为止仍然只有一个对象,但您可以使用ab来引用它。给了一个单个对象两个不同的变量名。)

修改a引用的对象(记住这也是b引用的同一个对象),以获得boo属性:

a.boo = "Yiss!"
>> "Yiss!"

确认b引用的对象(与a引用的对象相同)已更改:

b
>> Object {boo: "Yiss!"}

a引用一个新对象:

a = new Object()
>> Object {}

b仍然引用第一个对象:

b
>> Object {boo: "Yiss!"}

a再次引用原始对象:

a = b
>> Object {boo: "Yiss!"}

从原始对象中删除boo属性:

delete a.boo
>> true

确认boo属性已从b引用的对象中删除(与a引用的对象相同):

b
>> Object {}

确认boo属性已从a引用的对象中删除(与b引用的对象相同):

a
>> Object {}

从全局命名空间中删除变量名“a”:

delete a
>> true

变量名“a”不再存在:

a
>> Uncaught ReferenceError: a is not defined

变量b仍然引用原始对象:

b
>> Object {}

您似乎认为delete会破坏价值观。它不是。相反,它从对象中删除属性。由于全局变量是全局对象的属性,因此也可以删除它们(即,此处awindow.a相同)。

答案 2 :(得分:0)

JavaScript中的对象[几乎]总是通过引用传递。在您的情况下,ab 是相同的对象。

delete运算符不会删除对象或变量,而是删除属性。在您的示例中,您在全局范围内定义ab - 因此它们被视为window属性。 这是delete背后工作的唯一原因。