按引用传递JavaScript对象
请阅读下面代码中的注释,了解我在尝试什么 问 预期输出:根据JavaScript中的pass-by-reference机制,按引用传递JavaScript对象,javascript,Javascript,请阅读下面代码中的注释,了解我在尝试什么 问 预期输出:根据JavaScript中的pass-by-reference机制,objOne预计会在最后记录{},因为objTwo是用{}初始化的 var objOne = { x: 1, y: 2 }; var objTwo = objOne; // change the x vlaue to 2 by objTwo objTwo.x = 2; // Change the value of key x in objOne as well
objOne
预计会在最后记录{}
,因为objTwo
是用{}
初始化的
var objOne = {
x: 1,
y: 2
};
var objTwo = objOne;
// change the x vlaue to 2 by objTwo
objTwo.x = 2;
// Change the value of key x in objOne as well - pass by reference mechanism
console.log(objOne); // { x: 2, y: 2 }
/*** Pass by reference is understood in code, above this comment ***/
// Now what if objTwo initialized with empty object
objTwo = {};
console.log(objOne); // { x: 2, y: 2 } but expected output = {}
// As per pass by reference mechanism. objOne is expected to log {}, because objTwo was initialized with {}.
当你评估
objTwo = {};
Javascript将其解释为将objTwo重新分配给新的文本空对象,并保留其旧值
如果要通过引用从objOne中删除密钥,可以使用delete
关键字:
delete objTwo.x; // also deletes the x property of objOne
JavaScript按引用传递是不同的,只要您更改对象的属性(如obj.x=1),对象就会被视为引用,但对象变量本身的赋值(obj=[])会将其视为基于值的变量。
objTwo={}代码>的工作方式与您认为的不同。我通常建议将变量视为“指针”
objOne
和objTwo
是两个完全不同的变量。当您执行objTwo={}
,它所做的是将objTwo
变量指向另一个对象。它不会改变对象
变量
让我们想象一下:
var objOne = {
x: 1,
y: 2
};
// objOne -> { x: 1, y: 2 }
var objTwo = objOne;
// objOne -> { x: 1, y: 2 } <- objTwo
objTwo.x = 2;
// objOne -> { x: 2, y: 2 } <- objTwo (update object via objTwo variable)
objTwo = {};
// objOne -> { x: 2, y: 2 }, objTwo -> {}
var objOne={
x:1,
y:2
};
//对象->{x:1,y:2}
var objTwo=objOne;
//objOne->{x:1,y:2}{x:2,y:2}{x:2,y:2},objTwo->{
只有删除才能调用初始化状态
for(var i in objOne){
delete objOne[i];
}
@纳拉比诺维茨说
- Javascript总是按值传递,但当变量引用对象(包括数组)时,“值”是对对象的引用
- 更改变量的值不会更改基础基元或对象,它只是将变量指向新的基元或对象
- 但是,更改变量引用的对象的属性确实会更改基础对象
当两个变量指向同一个对象时,并不意味着它们现在神奇地“绑定”在一起
在您的例子中,objTwo={}
只是将objTwo
更改为指向您创建的新对象。当您将一个变量分配给另一个变量时,并不是这两个变量现在都通过引用链接;你误解了“参考传递”在这里的意思
保存对象的变量不会“直接”保存对象。它所持有的是对一个对象的引用。当您将引用从一个变量分配到另一个变量时,您正在复制该引用。现在,两个变量都包含对对象的引用。通过该引用修改对象会更改包含该对象引用的两个变量的对象
当您为其中一个变量指定一个新值时,您只是在修改该变量所持有的值。变量现在不再保存对对象的引用,而是保存其他内容。另一个变量仍然保留对原始对象的引用,赋值根本没有影响它。我同意接受的答案,这只是一些代码来支持它
let objOne = {x: 1, y: 2};
let objTwo = objOne; // referencing to same thing
objTwo.x = 2;
console.log(objOne, objTwo); // output {x:2, y:2}, {x:2, y:2}
let objThree = {};
objTwo = objThree; // notice this. Same as "objTwo = {}", except now you have objThree as initial reference
console.log(objOne, objTwo, objThree); // output {x:2, y:2}, {}, {}
通过更改objTwo引用或添加完整的新值(如问题示例所示),您可以很容易地注意到发生了什么。这就是通过引用传递的工作原理。在这里,objTwo指的是objTwo,因此无论您对objTwo做什么,在案例1中,objOne
和objTwo
都指同一个对象。因此,可以通过它们中的任何一个来更改x
。重新初始化objTwo
意味着它不再引用同一个对象。这不会导致所有其他现有引用变成{},而是引用的对象,而不是变量;发生的情况是,我更改为空object.JavaScript的引用根本没有“passbyreference”,句号。JavaScript是一种纯粹的传递值语言。passbyreference在计算机编程中有一个特殊的含义:它将变量的引用传递到函数中。JavaScript从来不会这样做。赋值不会更改对象,它会更改变量obj
“您误解了“按引用传递”在这里的意思”我想借此机会告诉他们JavaScript根本没有按引用传递。@jpmc26否。如果您赋值的不是对象,就不会有“引用”不再变量所持有的值是一个引用,但该变量也可以持有其他值。@Caleth:这纯粹是传递值。是,该值可以是对象引用。对象引用和其他任何引用一样都是值。是的,使用该值可以提供对象的引用语义,这是人们在说“按引用传递”时所关心的@Caleth:(如果你不@
非作者的人,他们不会收到你的注释通知。)这不是按引用传递的意思,因此,如果你遇到这些人,请向他们解释。:-)通过引用是计算机科学界的一个术语。它指的是将对变量的引用传递到函数中。JavaScript不能做到这一点。要理解像JavaScript这样的语言中的对象引用,最重要的一点是它们只是值。