javascript 设置一个变量等于另一个变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50840293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:18:11  来源:igfitidea点击:

Setting a variable equal to another variable

javascriptvariablesjavascript-objects

提问by KGraber

I have a few questions about setting a variable equal to another variable in JavaScript.

我有几个关于在 JavaScript 中设置一个变量等于另一个变量的问题。

Let's say we create an object, aand set b = a.

假设我们创建了一个对象,a并设置了b = a.

var a = {
  fname: "Jon",
  lname: "Smith",
  age: 50
}

var b = a;

I understand that if we change one of a's properties bwill also be changed because when we set b = awe don't clone a's data, but rather create a reference to a's data. For example if we set a.fname = "Sarah", the new value of b.fnamewill be "Sarah".

我知道如果我们更改a的属性之一b也会更改,因为当我们设置时,b = a我们不会克隆a的数据,而是创建对a数据的引用。例如,如果我们设置a.fname = "Sarah", 的新值b.fname将是"Sarah"

If we try to "clear" athough by setting a = {}, object bwill remain unchanged. I don't understand why manipulating an object in this way produces a different result than in the 1st example.

如果我们尝试a通过设置来“清除” a = {},对象b将保持不变。我不明白为什么以这种方式操作对象会产生与第一个示例不同的结果。



Also I have a question about the following scenario.

另外我对以下场景有疑问。

var x = 10;
var z = x;

If we then set x = 20, the value of zremains unchanged. Based on the behavior described in my 1st question, one would think that the new value of zwould reflect the new value of x. Could someone please explain what I am missing here?

如果我们然后设置x = 20, 的值z保持不变。根据我在第一个问题中描述的行为,人们会认为 的新值z将反映 的新值x。有人可以解释一下我在这里缺少什么吗?

Thank You!

谢谢!

回答by Scott Marcus

The really short answer to both your questions is that when you make one variable equal to another, a COPY of what's in the first variable is made and stored in the second variable- there is no linkage between the two variables.

对你的两个问题的真正简短的回答是,当你使一个变量等于另一个变量时,第一个变量中的内容被复制并存储在第二个变量中- 这两个变量之间没有链接。

But, read on for more details and why it can seem like there is a link in some cases...

但是,请继续阅读以了解更多详细信息以及为什么在某些情况下似乎存在链接...



JavaScript, like many languages, divides data into two broad categories: value types and reference types. JavaScript value types are its primitives:

与许多语言一样,JavaScript 将数据分为两大类:值类型和引用类型。JavaScript 值类型是它的原语

  • string
  • number
  • boolean
  • null
  • undefined
  • symbol
  • 细绳
  • 数字
  • 布尔值
  • 空值
  • 不明确的
  • 象征

When you assign any of these types to a variable, the actual data is stored in that variable and if you set one variable equal to another, a copy (not a linkage)of the primitive is made and stored in the new variable:

当您将这些类型中的任何一种分配给变量时,实际数据将存储在该变量中,如果您将一个变量设置为与另一个相同,则会制作原语的副本(而不是链接)并将其存储在新变量中:

var a = 10;  // Store the actual number 10 in the a variable
var b = a;   // Store a COPY of the actual number stored in a (10) in the b variable
a = 50;      // Change the actual data stored in a to 50 (no change to b here)
console.log(b);  // 10

When you work with reference types, something a little different happens. Assigning a variable to a reference type means that the variable only holds a reference to the memory location where the object is actually stored, not the actual object itself. So, when you do this:

当您使用引用类型时,会发生一些不同的事情。将变量分配给引用类型意味着该变量只保存对实际存储对象的内存位置的引用,而不是实际对象本身。所以,当你这样做时:

var a = {foo:"bar"};

adoes not actually store the object itself, it only stores the memory location for where the object can be found (i.e. 0x3C41A).

a实际上并不存储对象本身,它只存储可以找到对象的内存位置(即 0x3C41A)。

But, as far as setting another variable equal to the first goes, it still works as it did with primitives- - a copyof what's in the first variable is made and given to the second variable.

但是,就设置另一个变量等于第一个变量而言,它仍然像处理原语一样工作——制作第一个变量中的内容的副本并将其提供给第二个变量。

Here's an example:

下面是一个例子:

// An object is instantiated in memory and a is given the address of it (for example 0x3C41A)
var a = {}; 
 
// The contents of a (the memory location of an object) is COPIED into b.
// Now, both a and b hold the same memory location of the object (0x3C41A)
var b = a;

// Regardless of whether a or b is used, the same underlying object
// will be affected:
a.foo = "test";
console.log(b.foo); // "test"

// If one of the variables takes on a new value, it won't change
// what the other variable holds:
a = "something else";
console.log(b);   // The object stored in memory location (0x3C41A)

So, in your first tests, you've simply got two ways of accessing one object and then you change what ais holding (the memory location of the object) to a different object and therefore now you only have one way left to access the original object, through b.

因此,在您的第一个测试中,您只有两种访问一个对象的方法,然后您将a保存的内容(对象的内存位置)更改为不同的对象,因此现在您只剩下一种方法来访问原始对象对象,通过b



If we try to "clear" athrough by setting a = {}, object bwill remain unchanged. I don't understand why manipulating an object in this way produces a different result than in the 1st example.

如果我们尝试a通过设置“清除” a = {},对象b将保持不变。我不明白为什么以这种方式操作对象会产生与第一个示例不同的结果。

Because now we know that a = {}isn't clearing the object. It's just pointing aat something else.

因为现在我们知道这a = {}不是清除对象。它只是指向a别的东西。

回答by Chaz

Let me try to explain:

让我试着解释一下:

1) In your example aand bare references to one and the same object, while a.fname(or b.fname) is an attribute of that object. So when manipulating the attribute it will be changed in the object, while the references won't be affected, they still point to the same object, the object itself has been changed. a = {}on the other hand will just replace the reference to the object without affecting the object itself or b's reference to It.
It's no clearance btw you only just created a new reference to a new empty object.

1) 在您的示例中,aandb是对同一个对象的引用,而a.fname(或b.fname) 是该对象的一个​​属性。所以当操作属性时,它会在对象中改变,而引用不会受到影响,它们仍然指向同一个对象,对象本身已经改变了。a = {}另一方面,只会替换对对象的引用,而不会影响对象本身或b对 It 的引用。
顺便说一句,您只是创建了一个对新空对象的新引用,这并不重要。

2) These are not objects, so there is no reference you are directly manipulating the values. That' s because there's a difference between objects and primitives which might get confusing especially in the beginning if you're not used to working with strict types.

2)这些不是对象,因此没有直接操作值的参考。那是因为对象和原语之间存在差异,如果您不习惯使用严格类型,这可能会使您感到困惑,尤其是在开始时。

回答by steenbergh

In your first case:

在你的第一种情况下:

var a = {
  fname: "Jon",
  lname: "Smith",
  age: 50
}

var b = a;
a = {}

bremains unchanged because this is the sequence of events happening in the background:

b保持不变,因为这是在后台发生的事件序列:

  • You create an object at memory address 0x1234 with the data

    fname: "Jon",lname: "Smith",age: 50

  • A pointer to that memory block is stored ina.

  • Then that pointer is copied to b
  • 您使用数据在内存地址 0x1234 处创建一个对象

    fname: "Jon",lname: "Smith",age: 50

  • 指向该内存块的指针存储在a.

  • 然后将该指针复制到 b

At this point there are two references to the same bit of memory. Altering anything in that memory block will affect both the references to it.

此时有两个对同一位内存的引用。更改该内存块中的任何内容都会影响对它的引用。

  • a = {}doesn't clear out memory block 0x1234, but creates a new object on another memory location (0x1235) and stores a pointer to that block in a. The memory at 0x1234 remains unchanged because bis still pointing to it.
  • a = {}不会清除内存块 0x1234,而是在另一个内存位置 (0x1235) 上创建一个新对象并将指向该块的指针存储在a. 0x1234 处的内存保持不变,因为b仍然指向它。

There is a difference in this sort of memory management between simple variables and objects/pointers. Strings and numbers are of the simple variety and are 'passed by value' as opposed to being 'passed by reference' for objects.

简单变量和对象/指针之间的这种内存管理存在差异。字符串和数字是简单的种类,并且是“按值传递”而不是“按引用传递”对象。