С помощью массива JavaScript я могу сбросить его в пустое состояние с помощью одного присваивания:
array.length = 0;
Это заставляет массив «казаться» пустым и готовым к повторному использованию, и, насколько я понимаю, это отдельная «операция», то есть постоянное время.
Есть ли аналогичный способ очистки объекта JS? Я знаю, что могу итерировать его поля, удаляя их:
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }
но это имеет линейную сложность.
Я также могу просто выбросить объект и создать новый:
obj = {};
Но «беспорядочное» создание новых объектов приводит к проблемам с сборкой мусора на IE6. ( Как описано здесь )
javascript
performance
Левик
источник
источник
for (var prop in obj)
Ответы:
Я думаю, что короткий ответ на ваш вопрос - нет (вы можете просто создать новый объект).
В этом примере я считаю, что установка длины в 0 все равно оставляет все элементы для сборки мусора.
Вы можете добавить это в Object.prototype, если вы часто его используете. Да, он линейный по сложности, но все, что не будет делать сборку мусора позже, будет.
Это лучшее решение. Я знаю, что это не связано с вашим вопросом - но как долго нам нужно продолжать поддерживать IE6? Есть много кампаний, чтобы прекратить использование этого.
Не стесняйтесь поправлять меня, если есть что-то неправильное выше.
источник
Ну, рискуя сделать вещи слишком простыми ...
... может показаться довольно эффективным для очистки объекта в одной строке кода с минимумом страшных скобок. Все участники будут действительно удалены, а не оставлены как мусор.
Очевидно, что если вы хотите удалить сам объект, вам все равно придется сделать для этого отдельную функцию delete ().
источник
hasOwnProperty
в этом цикле. Я прочитал документы, но я все еще пытаюсь обернуть голову, каковы риски, если мы пропустимhasOwnProperty()
проверку?ES5
Решение ES5 может быть:
ES6
И решение ES6 может быть:
Производительность
Независимо от характеристик, самые быстрые решения, как правило, будут:
Причина, по которой
for..in
должен выполняться только мелкий или обычный объект, заключается в том, что он пересекает свойства, которые наследуются по прототипу, а не только собственные свойства, которые могут быть удалены. В случае , если не известно точно , что объект является простым и свойства перечислимы,for
сObject.getOwnPropertyNames
является лучшим выбором.источник
Вы можете попробовать это. Функция ниже устанавливает все значения свойств объекта на неопределенные. Работает также и с вложенными объектами.
источник
Итак, резюмируем ваш вопрос: вы хотите, насколько это возможно, избежать проблем с ошибкой IE6 GC. Эта ошибка имеет две причины:
Решение проблемы 1, по-видимому, заключается в следующем: уменьшить количество выделений; назначайте новые объекты и строки как можно меньше.
Решение проблемы 2 выглядит следующим образом: уменьшить количество «живых» объектов; удаляйте свои строки и объекты, как только они вам больше не нужны, и создавайте их заново при необходимости.
В некоторой степени эти решения противоречивы: сохранение небольшого количества объектов в памяти повлечет за собой большее выделение и перераспределение. И наоборот, постоянное повторное использование одних и тех же объектов может означать сохранение большего количества объектов в памяти, чем это строго необходимо.
Теперь на ваш вопрос. Будете ли вы сбрасывать объект, создавая новый или удаляя все его свойства: это будет зависеть от того, что вы хотите с ним делать потом.
Возможно, вы захотите присвоить ему новые свойства:
Не существует быстрого, простого в использовании способа очистки объекта JScript для повторного использования, как если бы это был новый объект - без создания нового. Это означает, что краткий ответ на ваш вопрос «Нет», как говорит Джтомпсон.
источник
Что-то новое, о чем стоит подумать, ожидая Object.observe в ES7 и с привязкой данных в целом. Рассматривать:
Таким образом, в этом случае № 2 может быть лучшим выбором.
источник
obj = {}
сделает фреймворк не осведомленным о каких-либо дальнейших изменениях объекта, поэтому ваши шаблоны не будут правильно отображаться. Вариант № 2, однако, будет работать правильно.Вы можете удалить реквизит, но не удаляйте переменные.
delete abc;
недопустим в ES5 (и выдает с использованием строго).Вы можете присвоить ему значение null, чтобы установить его для удаления в GC (не будет, если у вас есть другие ссылки на свойства)
Установка
length
свойства для объекта ничего не меняет. (это только, ну, устанавливает свойство)источник
length
0 в массиве (который является конкретным типом объекта - если вы мне не верите, попробуйте запуститьtypeof []
), он не только установит свойство, но и фактически очистит содержимое массива. , См. Stackoverflow.com/questions/1232040/…window.abc
потому что это опора в этом случае.Это давало мне неприятности целую вечность, так что вот моя версия, так как я не хотел пустой объект, я хотел один со всеми свойствами, но сбросил до некоторого значения по умолчанию. Вроде как новый экземпляр класса.
источник