数组奇怪的javascript变量行为

时间:2014-08-05 11:42:50

标签: javascript arrays variables

希望以前不要问这个问题。无论如何我找不到它。 我注意到这种变量行为似乎只发生在数组中。

以下是我通常期望变量的行为方式。

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问题,我很抱歉,但我刚刚注意到了。是这样的所有复杂类型?我想知道这种行为背后的原因。这样做会使语言达到什么目的?

5 个答案:

答案 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 |
+------+          +-----------+

请注意arrarr2中的只是对数组的引用,该数组存在于内存的其他位置。

因此,当您推送一个值时,事情会变为:

+------+
| arr  |------+
+------+      |   +-----------+
              +-->| (array )  |
+------+      |   +-----------+
| arr2 |------+   | length: 0 |
+------+          | 0: 1      |
                  +-----------+
  

对于所有复杂的类型,它是这样的吗?

是的,所有对象都是如此(标准数组只是JavaScript中的对象),以及新的类型数组。

要记住的关键是变量包含。当变量引用对象或数组时,变量中的是对象/数组的引用,而不是对象的副本。

牢牢掌握对象引用的价值就像(比方说)数字一样,对于理解JavaScript代码(以及其他几种语言中的代码,在这方面的工作方式,如Java)非常有益。

答案 1 :(得分:1)

我想我也可以回答为什么会这样:

javascript中有两种类型的值:

  1. 复杂类型
  2. 原始类型
  3. 复杂类型是我们通常称为对象的类型:

    []
    {}
    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;

在第一种情况下mk接收两个不同的副本10.赋值操作复制值,m上的任何更改都不会影响另一个,反之亦然(因为它们是两个)不同的副本)。

相反,数组是javascript中的引用类型

var arr = [],
    arr2 = arr;

赋值操作会复制地址,因此通过一个变量对对象的任何修改都会影响另一个。

答案 4 :(得分:0)

JavaScript中有两种变量(以及其他语言)。第一种保留用于所谓的"原始"类型,主要是数字,字符串和布尔值。第二种类型是"参考"类型是所有其他类型的对象。

您可以这样考虑:对于原始类型,每个值都存储在自己的抽屉中。例如,抽屉x的值为1,抽屉y的值为" John"等等。因此,当您访问抽屉x时,您将直接访问内部的值。

对于引用类型,您只需存储从隐藏在后面某处的内存位置检索此值的方向,而不是将变量的值存储在抽屉本身中。因此,当您复制"参考抽屉的内容时,#34;到另一个变量你没有复制值而只复制方向,所以现在你有两个抽屉,它们有方向来访问相同的值。

为什么这样做是相当复杂的,但基本上它与尽可能高效地管理程序内存有关。