将一个变量设置为另一个变量
将一个变量设置为另一个变量
这个问题已经有了答案::
我有几个关于在JavaScript中将一个变量设置为另一个变量的问题。
假设我们创建一个对象a
并将b = a
。
var a = { fname: "Jon", lname: "Smith", age: 50 } var b = a;
我理解如果我们更改a
的一个属性,则b
也会被更改,因为当我们设置b = a
时,我们不会克隆a
的数据,而是创建对a
数据的引用。例如,如果我们设置a.fname = \"Sarah\"
,则b.fname
的新值将是\"Sarah\"
。
但是,如果我们尝试通过设置a = {}
来“清除”a
,则对象b
将保持不变。我不明白为什么以这种方式操作对象会产生与第一个示例不同的结果。
还有一个关于以下场景的问题。
var x = 10; var z = x;
如果我们接着设置x = 20
,则z
的值仍然不变。根据我在第一个问题中描述的行为,人们会认为z
的新值将反映x
的新值。请问有人能解释一下我错过了什么吗?
谢谢!
在你的第一个案例中:
var a = { fname: "Jon", lname: "Smith", age: 50 } var b = a; a = {}
b
保持不变,因为这是后台发生的事件顺序:
-
你在内存地址0x1234创建一个对象,数据为
fname: "Jon",
lname: "Smith",
age: 50
-
指针指向那个内存块,并存储在
a
中。 - 然后将该指针复制到
b
中。
此时有两个对同一内存块的引用。更改该内存块中的任何内容都将影响对它的两个引用。
a = {}
并不清除内存块0x1234,而是在另一个内存地址(0x1235)上创建一个新对象,并将指针存储在a
中。内存中的0x1234保持不变,因为b
仍然指向它。
在这种内存管理方式中,简单的变量和对象/指针之间有区别。字符串和数字属于简单类型,是按值传递的,而对象是按引用传递。
回答你两个问题的简短答案是,当你让一个变量等于另一个变量时,第一个变量中的东西会被复制并存储到第二个变量中-两个变量之间没有链接。
但是,在某些情况下可能会产生链接,请继续阅读了解更多详细信息和原因...
像许多语言一样,JavaScript将数据分为两个广泛的类别:值类型和引用类型。JavaScript值类型是其原始值:
- 字符串
- 数字
- 布尔值
- null
- 未定义
- 符号
当您将任何这些类型分配给变量时,实际数据存储在该变量中,如果您将一个变量设置为等于另一个变量,则会复制(而不是链接)原始值并存储在新变量中:
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("a is: " + a); // 50 console.log("b is: " + b); // 10
当您使用引用类型时,会发生一些不同的事情。将变量分配给引用类型意味着变量仅保存到实际存储对象的内存位置的引用,而不是实际对象本身。所以,当你这样做:
var a = {foo:"bar"};
a
实际上并没有存储对象本身,它只存储了对象实际存储位置的内存地址(即0x3C41A)。
但是,就将一个变量设置为另一个变量一样,它仍然像用于原始类型的方法一样工作 ——复制第一个变量中的内容并将其给予第二个变量。
以下是一个例子:
// 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("a is: ", a); // The new string primitive stored in memory console.log("b is: ", b); // The object stored in memory location (0x3C41A)
因此,在您的第一次测试中,您只有两种访问对象的方法,然后您更改a
所持有的内容,将其更改为指向另一个对象,因此现在只有一种方法可以访问原始对象,即通过b
。
如果我们尝试通过设置
a = {}
来“清除”a
,则对象b
将保持不变。我不理解为什么用这种方式操作一个对象会产生与第一个示例不同的结果。
因为现在我们知道a = {}
并没有清除对象。它只是将a
指向其他内容。