Некоторое время назад я проводил рефакторинг устаревшего JS-кода и заметил, что PHPStorm жалуется на использование функции remove
: mySelect.remove(0)
- Invalid number of arguments, expected 0
. Я быстро просмотрел документацию и не нашел никакой информации об аргументе, поэтому удалил его без дальнейшего расследования (моя ошибка) и внедрил изменения.
Недавно мне сообщили об ошибке, из-за которой браузер зависает после изменения какого-либо элемента формы. Кажется, мое изменение нарушило форму.
Соответствующий код очень прост:
const mySelect = document.getElementById('mySelect');
while (mySelect.options.length > 0) {
mySelect.remove();
}
При правильном вызове remove
браузер зависает, так как кажется, что цикл бесконечен, но изменение вызова на недокументированный mySelect.remove(0)
заставляет его работать как положено.
Есть идеи по поводу такого поведения?
[проверено на Chrome]
недокументированная документация
не по теме: "поэтому я внес изменения и развернул без дальнейшего расследования" - вы работаете на Crowdstrike?
Краткое объяснение:
mySelect.remove(0)
правильно удаляет первый параметр (индекс 0) из элемента выбора на каждой итерации.
mySelect.remove()
удаляет весь элемент выбора из DOM на первой итерации, что приводит к бесконечному циклу, поскольку условие mySelect.options.length > 0 всегда истинно после удаления элемента выбора.
чтобы избежать путаницы, вы также можете использовать этот другой метод
while (mySelect.options.length > 0) {
mySelect.removeChild(mySelect.options[0]);
}
Спасибо за ваш ответ. Интересно, почему эта функция нигде не документирована. Я не нашел места ни в Интернете, ни во встроенной документации PHPStorm, где упоминалось бы об этом.
HTMLSelectElement.remove()
должен действовать как его одноименный метод в той же коллекции параметров, когда у него есть аргументы, и как его одноименный метод в интерфейсе ChildNode
, реализованном элементом интерфейса-предка HTMLSelectElement
, когда у него нет аргументов».
PHPStorm не может вам больше помочь, потому что он не знает, что
mySelect
является элементом выбора; если вы наведете курсор наmySelect
в своем коде, вы, вероятно, обнаружите, что там написаноHTMLElement
. Вы можете добавить, например. комментарий-подсказка/** @type {HTMLSelectElement} */
перед строкойconst mySelect
, означающий, что вы ожидаете, что это будетHTMLSelectElement
, и тогда вы, вероятно, должны увидеть более точную подпись для.remove()
.