我测试了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 {}
我只想清楚以下陈述是否属实: 在该对象的所有副本上都可以对对象的多个副本中的一个进行修改。如果副本或原件被新对象删除或替换,则不会影响其他副本。
答案 0 :(得分:4)
delete
所做的就是从对象中删除属性。它实际上并没有对属性的值做任何事情。
a
和b
相当于window.a
和window.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 {}
(你似乎认为这会以某种方式“复制”对象。这是不正确的:到目前为止仍然只有一个对象,但您可以使用a
和b
来引用它。给了一个单个对象两个不同的变量名。)
修改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
会破坏价值观。它不是。相反,它从对象中删除属性。由于全局变量是全局对象的属性,因此也可以删除它们(即,此处a
与window.a
相同)。
答案 2 :(得分:0)
JavaScript中的对象[几乎]总是通过引用传递。在您的情况下,a
和b
是相同的对象。
delete
运算符不会删除对象或变量,而是删除属性。在您的示例中,您在全局范围内定义a
和b
- 因此它们被视为window
属性。
这是delete
背后工作的唯一原因。