Я сталкиваюсь со следующей ситуацией. Я инициализирую массив и назначая ему свойство объекта.
var arr = [1,2,3,4,5];
var obj = { 'numbers': arr };
Я понимаю, что передал ссылку на мой массив arr
на мой объект obj
. Поэтому я могу сделать следующее:
arr.push(6);
console.log(obj);
будет отображено следующее, как и ожидалось:
{ numbers: [ 1, 2, 3, 4, 5, 6] }
Теперь о неожиданной части. Значение arr
изменяется через внешнее событие, и я хочу, чтобы значение obj.numbers
изменялось одновременно. Но это не так:
arr = [0,0,0,0,0];
console.log(arr);
console.log(obj);
arr --> [0,0,0,0,0]
obj --> { numbers: [ 1, 2, 3, 4, 5, 6] }
Таким образом, значение моей переменной arr
изменилось, но не свойство numbers
в моей переменной obj
.
Итак, мое единственное объяснение состоит в том, что как только вы выполняете назначение массиву, вы нарушаете старую ссылку и создаете новую ссылку. Это так?
И как бы мне присвоить мои новые значения [0,0,0,0,0]
моей переменной arr
и obj.numbers
(в то же время)?
Да, назначение с =
создает новую ссылку и избавляется от старой. Чтобы обойти это:
var arr = [1, 2, 3, 4, 5];
var obj = { 'numbers': arr };
console.log(arr === obj.numbers); // -> true
arr.length = 0;
var newArr = [0, 0, 0, 0, 0];
arr.push(...newArr);
console.log(arr === obj.numbers); // -> true
console.log(arr); // -> [0, 0, 0, 0, 0]
Установка длины, равной 0, очищает массив. Когда вы вставляете элементы в массив, он не создает новый массив, поэтому вы увидите изменения arr
и obj
.
Вы также можете использовать Array#splice
для нового массива.
var array = [1,2,3,4,5],
object = { numbers: array },
newArray = [41, 42, 43];
[].splice.apply(array, [0, array.length].concat(newArray));
console.log(object);
Я не нашел точной документации по этому поводу, но после некоторых экспериментов я пришел к выводу, что задание действительно создает новую ссылку.
Так я решил это решить.
arr.splice(0);
[0,0,0,0,0].map(el => arr.push(el);
Это дает мне следующий ожидаемый результат.
console.log(arr);
console.log(obj);
arr --> [0,0,0,0,0]
obj --> { numbers: [0,0,0,0,0] }
Кстати, то же самое верно для объектов, что было бы логично, так как массивы - это тип объекта.
Он работает правильно. Переменная - это место, где вы сохраняете ссылку. Экономия в arr
другой ссылки.
Вы можете обновить первый массив, используя этот код.
arr.length = 0;
arr.push(...[0, 0, 0, 0, 0]);
slice
метод не поможет вам, потому что он возвращает новую копию массива.
arr
, поэтому arr
теперь выглядит как [[0, 0, 0, 0, 0]]
. Это не то, что хотел вопрос.
arr.slice(0);
это не имеет смысла без назначения.slice
создает новый массив, сохраняя исходный массив без изменений. Таким образом, поскольку вы не сохраняете результат, в основном эта операция нагревает только ваш процессор. Затем[0,0,0,0,0].map(el => arr.push(el))
снова семантическиmap
следует использовать для создания нового массива с «отображаемыми» элементами. Поскольку у вас нет назначения, лучше использоватьforEach
.