为什么javascript对象值被更改?

为什么javascript对象值被更改?,javascript,object,Javascript,Object,有谁能向我解释一下为什么输出值改为“20,2”而不是原来的“1,2” 变量x={ 答:1,, b:2 }; 变量y=x; y、 a=20; document.getElementById(“demo”).innerHTML=x.a; document.getElementById(“demo1”).innerHTML=x.b; 在上面的y行中,传递的是x的引用,而不是整个对象x。对对象所做的任何更改都将反映在包含对象引用的所有变量中 因为它是相同的引用(存储对象的内存位置的相同地址),

有谁能向我解释一下为什么输出值改为“20,2”而不是原来的“1,2”


变量x={ 答:1,, b:2 }; 变量y=x; y、 a=20; document.getElementById(“demo”).innerHTML=x.a; document.getElementById(“demo1”).innerHTML=x.b;

在上面的
y
行中,传递的是
x
的引用,而不是整个对象x。对对象所做的任何更改都将反映在包含对象引用的所有变量中

因为它是相同的
引用
(存储对象的内存位置的相同地址),所以x和y现在都是相同的引用,因此更改一个将更改存储的值,现在由于它们是相同的引用,它们将输出相同的对象值

我想补充一些额外的东西,使这个答案更有成效

浅拷贝

浅复制是对象的逐位复制。将创建一个新对象 具有原始对象中值的精确副本的。如果有的话 对象的字段是对其他对象的引用,只是 复制参考地址,即仅复制内存地址 抄袭的

范例

let x={"a":1,"b":2};
let y=x;  //It makes a copy of the reference to x into y
因此,x和y的地址将是相同的,即它们将指向相同的内存位置。 所以如果你这么做

y.a=9;
现在当你在屏幕上打印y时

console.log(y) // it prints {"a":9,"b":2};
但有趣的是,当你打印x时

console.log(x)  // it also prints {"a":9,"b":2};
那么现在如何改变这种情况呢??。解决方案是深度复制

深度复制

深度副本复制所有字段并动态复制 字段指向的已分配内存。深度复制发生在 对象将与其引用的对象一起复制

用Lehman术语来说,您创建一个变量y,将其分配到不同的内存位置,复制x的所有成员,将复制的成员分配给y

最简单的方法是将对象串化

let y=JSON.parse(JSON.stringify(x))
现在如果我们这样做了

y.a=9
并打印y

console.log(y) // it prints {"a":9,"b":2};
如果我们打印x

console.log(x) //  it prints {"a":1,"b":2};
///浅拷贝
设x={
“a”:1,
“b”:2
};
设y=x;
y、 a=9;
控制台日志(y);
控制台日志(x);
//深度复制
设z={
“a”:1,
“b”:2
};
让t=JSON.parse(JSON.stringify(z));
t、 a=9;
console.log(“z:”,z);

console.log(“t:,t)
您将
y
指向
x
的引用,该引用本身指向对象
{a:1,b:2}

所以在记忆中它是:

x --> {a:1,b:2}
执行
y=x
后,它将变为:

y --> x --> {a:1,b:2}
或者简单地说:

x --> {a:20,b:2}
         ^
         |
y -------
现在,当您执行
y.a=20
操作时,由于
y
x
都指向同一对象,因此当对象的属性通过引用
x
y
中的任何一个进行更改时,更改将反映在两个引用中:

y --> {a:20,b:2}
        ^
        |
x -------

这就是为什么当你得到
x.a

时,你会得到
20,2
,这是因为
y
x
都指向同一个内存位置。如果你想要一个单独的副本,那么深度复制对象
JSON.parse
&
JSON.stringify

var x={
答:1,,
b:2
};
var y=JSON.parse(JSON.stringify(x));
y、 a=20;
document.getElementById(“demo”).innerHTML=x.a;
document.getElementById(“demo1”).innerHTML=x.b


JS通过引用传递对象,有一些与此相关的深入问题:由于您似乎对JavaScript不熟悉,我强烈建议不要使用
var
,因为这被认为是一种不好的做法。您应该使用
let
const
@Seblor我认为在前端JS中使用
var
没有什么错,事实上,如果您的目标是获得一系列良好的浏览器支持,那么我们(不幸的)仍然不得不完全避免使用let/const。@DBS虽然我理解您的意思,我真的认为
var
的使用和浏览器支持应该留给Transpiler(比如Babel)来完成。如果人们继续使用
var
,他们以后很难改变。另外,使用较新的ECMAScript版本通常会提高代码的可读性。
y --> {a:20,b:2}
        ^
        |
x -------