Javascript 为什么不是';当发生重新分配时,此对象是否复制为空?
假设我创建一个对象,复制它(通过引用),然后使其无效:Javascript 为什么不是';当发生重新分配时,此对象是否复制为空?,javascript,javascript-objects,Javascript,Javascript Objects,假设我创建一个对象,复制它(通过引用),然后使其无效: 让obj={ 道具:“一” } 让otherObj=obj console.log(otherObj==obj)//符合事实的 控制台日志(对象道具)//一 obj=null; 控制台日志(其他对象道具)//这不应该是未捕获的TypeError:无法读取null的属性“prop”?否,因为引用在您进行新赋值时丢失,所以其他obj仍将包含旧引用 换句话说,由于您修改了对象(例如,更改其某些字段),则otherObj和obj都将看到更新,但当
让obj={
道具:“一”
}
让otherObj=obj
console.log(otherObj==obj)//符合事实的
控制台日志(对象道具)//一
obj=null;
控制台日志(其他对象道具)//这不应该是未捕获的TypeError:无法读取null的属性“prop”?
否,因为引用在您进行新赋值时丢失,所以其他obj仍将包含旧引用
换句话说,由于您修改了对象(例如,更改其某些字段),则
otherObj
和obj
都将看到更新,但当您重新分配其中一个时,您会破坏绑定,并且每个对象都将引用内存中的不同位置。您必须区分对象和对该对象的引用。变量obj
和otherObj
只保留对t的引用对象,内存中指向该对象的指针。它们不是对象的副本,也不是同一对象。。它们指向同一对象
为了更清楚地说明这一点,我将逐行解释。当您这样做时:
let obj = {
prop: 'one'
}
您正在创建一个新引用,如下所示:
obj
只指向对象所在的内存点,称为引用。接下来,您可以:
let otherObj = obj
这相当于:
在这里,您将obj
的引用分配给otherObj
。它们现在都引用内存中的同一对象,尽管它们彼此完全独立。otherObj
是obj
的引用,因此它们都引用相同的对象,但是分开的。根据链接:
在这种情况下,将创建一个新对象B,并将a的字段值复制到B
[……]
如果字段值是对对象的引用(例如,内存地址)它复制引用,因此引用与对象相同的对象
最后,您可以这样做:
obj = null
这是这样的:
从
obj
到内存中对象的引用基本上是断开的,obj
现在指向null
,或者什么都没有。由于obj
和otherObj
彼此独立,因此otherObj
不会发生任何事情,它仍然指向内存中的对象。obj
和otherObj本身是独立的引用,但引用同一个对象。当您在内存中修改对象时,它会反映在两个引用上,但当您通过断开对内存位置的引用来修改引用时,另一个引用不会发生任何变化。否,要理解您为什么需要理解“引用”的概念
在您的示例中,这段代码“创建”了您的对象:
let obj = {
prop: 'one'
}
在这种情况下,“obj”不是对象本身(像内存位置),而是一个对象“引用”-基本上它是指向指针的指针
在将“obj”设置为null之前,您还将“otherObj”指定为对同一对象的引用。此时您有2个引用
当您将“obj”设置为null时,该对象仍然存在,并且仍然被“otherObj”引用。它将被保存在内存中,至少直到它不再被“otherObj”引用为止”“不是。如果您将两个引用都设置为null,那么您将无法再访问对象本身,并且很可能使它可以被Javscript引擎释放
这是一个非常重要的概念——如果将变量传递给函数,则该参数是对对象的“引用”(字符串和数字等基本上不可变的东西除外)。您可以在函数外部重新分配变量,参数将保持不变
另外,在另一面,当两个引用都指向同一对象时,对成员的更改将通过两个引用反映出来。如果你想要两个不同的副本,你必须做像“克隆”一个对象这样的事情——而不仅仅是引用它
理解引用对于在Javascript中管理闭包至关重要。您应该区分深度副本和浅层副本。你所做的叫做浅拷贝。以下是可视化:
浅拷贝
深度复制
对于浅拷贝,两个对象(obj
和otherObj
)引用相同的内存位置。这就是为什么更改一个对象的值时,另一个对象也会更新
同时,对于深度副本,每个对象都有自己的内存位置。更改一个对象的值时,它不会影响另一个对象
您可以从中了解更多信息。否,因为变量在JavaScript中是非类型化的。这意味着JavaScript引擎可以根据包含的信息确定变量的类型。在Visual Basic中,一种非常类似的变量称为
所以如果你说
let otherObj = obj;
如果obj
是一个对象值,那么现在有两个变量知道它们是对象,并且具有相同的对象值(不必讨论如何将对象实现为引用)
所以如果你现在执行
obj = null;
obj
的值被值null
覆盖(顺便说一句,它有一个数据类型“null”,它只支持一个值:null)
显然,给一个变量赋值并不能改变另一个变量的值。编程语言依赖于此
因此,在更新了obj
的值之后,otherObj
包含与之前相同的对象值:属性为“prop”且值为“one”的对象 不,您只是更改var指向的对象,而不是目标本身。如果修改了对象,两个变量都会反映这一点。将第二个var视为别名;您删除的是昵称,而不是人。