Когда вы делаете
var myArray = new Array();
Вы создаете объект в памяти и сохраняете ссылку на этот объект в переменной myArray
.(Ссылка похожа на указатель в C / C ++. Это значение указывает движку JavaScript, где находится объект.) Например:
+−−−−−−−−−+
| myArray |
+−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| ref |−−−−−−−−−−>| instance of an array |
+−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
| length = 0 |
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
Когда вы делаете:
var n = 2;
Фактическое значение 2 сохраняется в n
:
+−−−−−−−−−+
| n |
+−−−−−−−−−+
| 2 |
+−−−−−−−−−+
Это существенное различие между типами примитивов и объектов.(Строки немного размыты, но вы можете притвориться, что примитивные строки в JavaScript действуют так же, как числа, и поэтому движок скрывает от вас некоторые детали.)
Это важное различие, потому что JavaScript - этопросто передать по значению языка, поэтому, когда вы вызываете функцию и передаете в нее аргументы, передаются значения , а не переменные.Рассмотрим:
function foo(index, a) {
return a[index];
}
Функция foo
принимает индекс и массив и возвращает значение элемента в массиве с этим индексом.
x = foo(n, myArray);
Это вызывает foo
и передает значение из n
(2) и значение из myArray
(ссылка на массив).Таким образом, index
получает то же значение n
has (2), а a
получает то же значение myArray
(ссылка на массив).Поскольку значение в случае a
и myArray
является ссылкой на массив, они оба ссылаются на одного и того же массива:
+−−−−−−−−−+
| myArray |
+−−−−−−−−−+
| ref |−−−−−−−+
+−−−−−−−−−+ |
| +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−+ +−−−>| instance of an array |
| a | | +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−+ | | length = 0 |
| ref |−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−−−−−−−−+
+−−−−−−−−−+
+−−−−−−−−−+
| n |
+−−−−−−−−−+
| 2 |
+−−−−−−−−−+
+−−−−−−−−−+
| index |
+−−−−−−−−−+
| 2 |
+−−−−−−−−−+
То же самое верно для присваиванияпо той же причине: переменная слева от =
получает значение выражения справа от него.
var n2 = n;
var a2 = myArray;
n2
получаетзначение n
(2), а a2
получает значение myArray
(ссылка на массив).Если бы мы поставили диаграммы myArray
, a2
, n
и n2
, диаграмма была бы идентична приведенной выше для аргументов foo
index
и a
.
Поскольку myArray
и a
указывают на один и тот же массив (ссылаются на один и тот же объект), если они выполняют операции mutator над массивом, результаты видны через любую ссылку.Например, добавление нового элемента в массив является мутаторной операцией, он меняет объект на месте:
alert(myArray.length); // 0
alert(a.length); // 0
a.push("test");
alert(myArray.length); // 1
alert(a.length); // 1
Важно понимать, что там произошло. переменные myArray
и a
не были изменены, но объект, на который они ссылаются, имеет.В отличие от этого:
a = someOtherArray;
Теперь a
полностью указывает куда-то еще, его значение больше не совпадает со значением myArray
, и поэтому нессылаясь на тот же объект.
Не по теме : лучший способ написать
var myArray = new Array();
- это
var myArray = [];
конечный результат тот же (новый массив создан и назначен на myArray
), но второй короче, немного эффективнее и гарантирует, что вы получите массив (тогда как первый может , в необычной ситуации, не дать вам массив - если у кого-то есть затененный символ Array
).
Аналогично, вы можете написать
var obj = new Object();
какэтот
var obj = {};
... который имеет аналогичные преимущества по тем же причинам.