假设我创建了一个对象,复制它(通过引用)然后使其无效:
let obj = {
prop: 'one'
}
let otherObj = obj
console.log(otherObj === obj); //true
console.log(obj.prop); //one
obj = null;
console.log(otherObj.prop); //shouldn't this be Uncaught TypeError: Cannot read property 'prop' of null"?

是不是otherObj
也是空的,因为它们是同一个对象?
答案 0 :(得分:1)
您必须区分对象和引用到该对象。变量obj
和otherObj
只保存对象的引用,该对象是指向内存的指针。 它们不是对象的副本,并且它们不是同一个对象。他们指向到同一个对象。
为了更清楚地说明这一点,我将逐行解释。当你这样做时:
let obj = {
prop: 'one'
}
您正在创建一个新的引用,如下所示:
obj
只指向对象所在的内存中的一个点,称为引用。接下来,你做:
let otherObj = obj
这相当于:
在此,您将 obj
的引用分配给otherObj
。它们现在都指向内存中的相同对象,尽管它们完全相互独立。 otherObj
是obj
obj = null
的引用,因此它们都引用相同的对象但是是分开的。根据链接:
在这种情况下,会创建一个新对象B,并将A的字段值复制到B。
[...]
如果字段值是对象的引用(例如,内存地址),则复制引用,因此引用与A相同的对象
最后你这样做:
obj
这是这样的:
从obj
到内存中对象的引用基本上已被切断,null
现在指向obj
,或者什么都没有。由于otherObj
和otherObj
彼此独立,因此obj
没有任何反应,它仍然指向内存中的对象。 otherObj
和refreshStuff()
本身是单独的引用,但引用相同的对象。当您修改内存中的对象时,它会反映在两个引用上,但是当您通过断开对内存位置的引用来修改引用时,另一个没有任何反应。
答案 1 :(得分:0)
不,因为在您进行新作业obj = null
的确切时刻,参考文献会丢失,所以otherObj仍会包含旧参考文献。
换句话说,既然您修改了对象(例如,更改了某些字段),otherObj
和obj
都会看到更新,但是当您重新分配其中一个时,就会中断债券和每一个都将指向记忆中的不同位置。
答案 2 :(得分:0)
不,要理解为什么你需要理解“参考”的概念。
在您的示例中,这段代码“创建”了您的对象:
let obj = {
prop: 'one'
}
在这种情况下,“obj”不是对象本身(如内存位置),而是对象“引用” - 基本上它是指向指针的指针。
在将“obj”设置为null之前,还将“otherObj”指定为对SAME对象的引用。此时你有2个引用。
当您将“obj”设置为null时,该对象仍然存在并仍然被“otherObj”引用。它将被保存在内存中,至少在它不再被“otherObj”引用之前。如果将两个引用都设置为null,那么您将无法再访问该对象本身,并且可能会使其可供Javscript引擎释放。
这是一个非常重要的概念 - 如果将变量传递给函数,该参数是对象的“引用”(除了字符串和数字之类的东西,它们本质上是不可变的)。您可以在函数外部重新分配变量,参数将保持不变。
另外,在另一方面 - 虽然两个引用指向同一个对象,但成员的更改都会被两个引用反映出来。如果你想要两个不同的副本,你必须做一些事情,比如“克隆”一个对象 - 而不仅仅是引用它。
了解引用对于管理Javascript中的闭包至关重要。
答案 3 :(得分:0)
您应该区分深拷贝和浅拷贝。你正在做的事情被称为浅拷贝。这是可视化:
浅拷贝
深层复制
对于浅层副本,您的两个对象(obj
和otherObj
)都指向相同的内存位置。这就是为什么当你改变一个对象的值时,另一个对象也会被更新。
同时,使用深层副本,每个对象都有自己的内存位置。当您更改一个对象的值时,它不会影响另一个。
您可以从此post了解更多信息。
答案 4 :(得分:-1)
不,因为变量在JavaScript中是无类型的。这意味着JavaScript引擎可以根据其包含的信息确定变量的类型。在Visual Basic中,一种非常相似的变量称为"variant"。
所以,如果你说
let otherObj = obj;
其中obj
是一个对象值,你现在有两个变量,它们知道它们是对象并且具有相同的对象值(不考虑如何将对象实现为引用)。
所以如果你现在执行
obj = null;
obj
的值覆盖了值null
(顺便提一下,数据类型为“null”,只支持一个值: null )。
显然,为一个变量赋值是不应该改变另一个变量中保存的值。编程语言取决于此。
因此,在更新obj
的值之后,otherObj
包含与之前相同的对象值:具有值“prop”的属性为“prop”的对象。