Создает ли присвоение массива новую ссылку

1

Я сталкиваюсь со следующей ситуацией. Я инициализирую массив и назначая ему свойство объекта.

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 (в то же время)?

Теги:

4 ответа

2
Лучший ответ

Да, назначение с = создает новую ссылку и избавляется от старой. Чтобы обойти это:

  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.

1

Вы также можете использовать 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);
0

Я не нашел точной документации по этому поводу, но после некоторых экспериментов я пришел к выводу, что задание действительно создает новую ссылку.

Так я решил это решить.

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] }

Кстати, то же самое верно для объектов, что было бы логично, так как массивы - это тип объекта.

  • 1
    arr.slice(0); это не имеет смысла без назначения. slice создает новый массив, сохраняя исходный массив без изменений. Таким образом, поскольку вы не сохраняете результат, в основном эта операция нагревает только ваш процессор. Затем [0,0,0,0,0].map(el => arr.push(el)) снова семантически map следует использовать для создания нового массива с «отображаемыми» элементами. Поскольку у вас нет назначения, лучше использовать forEach .
  • 0
    Я хотел использовать сплайс
0

Он работает правильно. Переменная - это место, где вы сохраняете ссылку. Экономия в arr другой ссылки.

Вы можете обновить первый массив, используя этот код.

arr.length = 0;
arr.push(...[0, 0, 0, 0, 0]);

slice метод не поможет вам, потому что он возвращает новую копию массива.

  • 0
    Вы помещаете массив в arr , поэтому arr теперь выглядит как [[0, 0, 0, 0, 0]] . Это не то, что хотел вопрос.
  • 0
    @ArnavAggarwal ты прав. Я исправил это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню