希望以前不要问这个问题。无论如何我找不到它。 我注意到这种变量行为似乎只发生在数组中。
以下是我通常期望变量的行为方式。
var k = 10,
m = k;
alert(m); //10
k+=1;
alert(m); //10
现在看一下它们在数组中的表现。
var arr = [],
arr2 = arr;
alert(arr2); // empty
arr.push(1);
alert(arr2); // 1
似乎数组变量只是对同一数组的引用,数字代表两个具有相同值的不同数字。
如果这是一个noob问题,我很抱歉,但我刚刚注意到了。是这样的所有复杂类型?我想知道这种行为背后的原因。这样做会使语言达到什么目的?
答案 0 :(得分:2)
在您的第一个代码块中,您将从
开始+-------+ +--------------+ | k: 10 | | m: undefined | +-------+ +--------------+
然后这一行:
m = k;
将k
中的值复制到m
:
+-------+ +-------+ | k: 10 | | m: 10 | +-------+ +-------+
然后k+=1
更改了k
中的值,这对m
没有影响:
+-------+ +-------+ | k: 11 | | m: 10 | +-------+ +-------+
在第二个代码块中,您将从这开始:
+------+ | arr |------+ +------+ | +-----------+ +-->| (array ) | +------+ | +-----------+ | arr2 |------+ | length: 0 | +------+ +-----------+
请注意arr
和arr2
中的值只是对数组的引用,该数组存在于内存的其他位置。
因此,当您推送一个值时,事情会变为:
+------+ | arr |------+ +------+ | +-----------+ +-->| (array ) | +------+ | +-----------+ | arr2 |------+ | length: 0 | +------+ | 0: 1 | +-----------+
对于所有复杂的类型,它是这样的吗?
是的,所有对象都是如此(标准数组只是JavaScript中的对象),以及新的类型数组。
要记住的关键是变量包含值。当变量引用对象或数组时,变量中的值是对象/数组的引用,而不是对象的副本。
牢牢掌握对象引用的价值就像(比方说)数字一样,对于理解JavaScript代码(以及其他几种语言中的代码,在这方面的工作方式,如Java)非常有益。
答案 1 :(得分:1)
我想我也可以回答为什么会这样:
javascript中有两种类型的值:
复杂类型是我们通常称为对象的类型:
[]
{}
new String()
new Date()
现在原始类型是:
'a string'
23
true
所以这里的答案是引用在复杂类型和基本类型上的行为不同。
var aString = 'myString';
var refString = aString;
在这个例子中," aString"的值被复制到refString。它们是两个完全独立的价值观。但引用复杂类型:
var anArray = [];
var refArray = anArray;
var anObject = {};
var refObject = anObject;
在这种情况下,两个变量中的数组完全相同,对象也是如此。
这也转移到检查平等:
'my string' === 'my string' // true
23 === 23 // true
true === true // true
Javascript实际上只是看到值看起来像彼此,而不是它在内存中是完全相同的值。看看复杂的类型:
{} === {} // false
[] === [] // false
var myObject = {};
var myObjectReferenced = myObject;
myObject === myObjectReferenced // true
这是JavaScript理解的一个非常重要的核心概念,或者您将面临更改您认为独特的对象的高风险,但实际上是共享的。
希望这是一个好的解释。
答案 2 :(得分:0)
两个数组对象都指向相同的变量。这就是为什么一个人会改变其他人会受到影响
答案 3 :(得分:0)
数字是javascript中的原语。这意味着实际数据直接存储在变量本身上。
var k = 10,
m = k;
在第一种情况下m
和k
接收两个不同的副本10.赋值操作复制值,m上的任何更改都不会影响另一个,反之亦然(因为它们是两个)不同的副本)。
相反,数组是javascript中的引用类型
var arr = [],
arr2 = arr;
赋值操作会复制地址,因此通过一个变量对对象的任何修改都会影响另一个。
答案 4 :(得分:0)
JavaScript中有两种变量(以及其他语言)。第一种保留用于所谓的"原始"类型,主要是数字,字符串和布尔值。第二种类型是"参考"类型是所有其他类型的对象。
您可以这样考虑:对于原始类型,每个值都存储在自己的抽屉中。例如,抽屉x的值为1,抽屉y的值为" John"等等。因此,当您访问抽屉x时,您将直接访问内部的值。
对于引用类型,您只需存储从隐藏在后面某处的内存位置检索此值的方向,而不是将变量的值存储在抽屉本身中。因此,当您复制"参考抽屉的内容时,#34;到另一个变量你没有复制值而只复制方向,所以现在你有两个抽屉,它们有方向来访问相同的值。
为什么这样做是相当复杂的,但基本上它与尽可能高效地管理程序内存有关。