Почему не надо удалять все элементы массива, переназначая его на [ ]?

от автора

Очень часто бывают моменты, когда мы хотим удалить все элементы массива, как вариант, у нас есть список задач, и мы хотим удалить все задачи одновременно.

Рассмотрим такой список элементов:

let items = ["tea", "coffee", "milk"];

Чтобы удалить все элементы из массива, мы устанавливаем его значение в пустой массив

items = [];

Это работает отлично, и вы обнаружите, что данный пример используют постоянно. Но с этим есть проблема …

Посмотрим на следующий код:

let items = ["tea", "coffee", "milk"]; let copy = items;

Здесь мы создаем переменную copy и присваиваем ей ссылку на массив элементов, так что copy фактически указывает на массив items.

Убедимся в этом проверив их индивидуальные значения

console.log(items); // ["tea", "coffee", "milk"] console.log(copy); // ["tea", "coffee", "milk"]

Всё как и ожидалось.

Теперь, если мы изменим какой-либо из элементов, он изменит сам исходный массив, так как это просто ссылка, а не точная копия.

copy[2] = "oranges"; console.log(items); // ["tea", "coffee", "oranges"] console.log(copy); // ["tea", "coffee", "oranges"]

Но если мы хотим удалить все элементы массива items, мы, обычно, делаем так:

items = [];

Теперь, если мы проверим значения items и copy снова

console.log(items); // [] console.log(copy); // ["tea", "coffee", "oranges"]

Как вы можете видеть, массив items пуст, но вот переменная copy все еще содержит исходный массив и не очистилась.

Это произошло по тому, что когда мы написали items = [], переменная фактически создала новый пустой массив и присвоила его элементам, чтобы не изменять переменную copy.

Для не примитивных типов данных, таких как массив(array), или объект(object), когда мы присваиваем какое-либо значение, оно устанавливает не фактическое значение, а только ссылку на выделенный адрес памяти, где хранится эта переменная.

Поэтому, когда мы говорим, array = [], [] — это краткий способ выделения некоторого пространства в памяти без данных, поэтому массив будет содержать только ссылку на выделенное пространство памяти.

То же самое относится и к объектам. Когда мы говорим obj = {name: ‘David’}, переменная obj содержит не сам объект, а просто ссылку на выделенное пространство памяти, и в этом пространстве памяти сохраняется фактический объект.

let obj = { name: 'David' }; let newObj = obj; console.log(obj); // { name: 'David' } console.log(newObj); // { name: 'David' } obj = null; console.log(obj); // null console.log(newObj); // { name: 'David' }

Чтоб исправить это неподобство есть два способа:

  1. Установите длину массива в 0:
    let items = ["tea", "coffee", "milk"]; let copy = items; console.log(items); // ["tea", "coffee", "milk"] console.log(copy); // ["tea", "coffee", "milk"] items.length = 0; console.log(items); // [] console.log(copy); // []
  2. Используйте метод splice массива:
    let items = ["tea", "coffee", "milk"]; let copy = items; console.log(items); // ["tea", "coffee", "milk"] console.log(copy); // ["tea", "coffee", "milk"] // удаляем элементы массива, начиная с позиции 0 до последнего элемента длины массива items.splice(0, items.length); console.log(items); // [] console.log(copy); // []

Этот способ решает нашу задачу, потому что они фактически изменяют исходный массив, а не просто изменяют ссылку на элементы, как в случае с items = [];

Заключение:

Мы не должны создавать дополнительные ссылки для массива или объекта, так как это может привести к нежелательному результату в будущем. Если вы уверены, что нет никаких ссылок(*и не появится) на исходный массив, который нам нужно очистить, то вы можете использовать array = [], чтобы очистить его, иначе используйте любой из двух вышеперечисленных способов, чтобы очистить массив.

Сделаем web лучше.

ссылка на оригинал статьи https://habr.com/ru/post/497862/