Записки самоучки

Сентябрь 18, 2006

Как удалить элемент массива в JavaScript?

Filed under: JavaScript — 4matic @ 7:39 пп

Тема массивов в JS — это отдельная тема. Сегодня «узнал» как удалить искомый элемент массива. Все оказалось не так просто. При определенных вариантах решениях этой задачи могут возникнуть грабли. Для удаления элемента массива нужно знать имя элемента массива. А так же нужно знать о существовании метода splice() или оператора delete.

Начнем с splice(), а delete оставим на закуску. Метод splice() — это стандартный метод, т.е. он указан в стандартной спецификации ECMA. Не смотря на это, есть замечания по поводу поддержки этого метода различными браузерами. Так же я не буду описывать сигнатуру метода. Кому интересно пусть RTFM. Смысл функции в том, что бы заменить значения в перечисленных элементах массива на новые значения, если не будут указаны новые значения, то указанные элементы массива просто удалить. Все до безобразия просто, как долото.

Что касается оператора delete. Этот оператор тоже стандартный. Кому нужны подробности — RTFM. Оператор удаляет свойства объекта. Что касается массивов, то здесь нас ждут грабли. Оператор delete удалит элемент массива, но не обновит значение свойства length искомого массива. Перебирая все элементы массива классическим циклом for(i=0;i<n;i++), вы выполните одну лишнюю итерацию, которая при определенных обстоятельствах может вызвать ошибку, которую будет тяжело сходу найти.

На закуску код, написанный на коленке, для деомнстрации описанного выше:

<SCRIPT language="JavaScript"> <!-- var a = new Array(); a[10] = [1, 2, 3]; function showDel() { n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } a[10].splice(1, 1); n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } a[10].push(a[10].length + 1); n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } delete a[10][1]; n = a[10].length; alert('length = ' + n); for (i = 0; i<n; i++) { alert('i = ' + i + ' val = ' + a[10][i]); } } //--> </SCRIPT> <INPUT onclick="showDel()" type="reset" value="Сброс">

13 комментариев »

  1. Привет!

    Хочу прицепиться к тексту: «Результатом работы delete будет… присвоение искомому элементу значения undefined.»

    На самом деле просто удаляется свойство (поле) объекта, undefined не присваивается.

    комментарий от Zeroglif — Сентябрь 21, 2006 @ 10:12 пп

  2. Вы правы. Свойство удаляется, а значение свойства length не обновляется. Я некорректно сформулировал поведение свойства объекта при работе с ним оператора delete. Просто хотелось доходчивее объяснить. Текст исправляю. Спасибо за указание на ошибку.

    комментарий от 4matic — Сентябрь 21, 2006 @ 10:32 пп

  3. На самом деле, свойство length массива (точнее, объекта, созданного конструктором Array) равно наибольшему использованному индексу + 1. Глядите в статью «(Re-)introduction to JavaScript» (без труда отыщете гуглом). Поэтому удаляй из середины элементы, не удаляй — результат (для length) будет тем же самым.
    var arr = [];
    arr[0] = {};
    arr[100] = {};
    alert(arr.length); // 101, не 2

    Как это работает с объектом arguments или коллекцией DOM-нодов — не знаю. Проверяйе сами. ))

    комментарий от Andrew R — Октябрь 4, 2006 @ 3:52 пп

  4. 2 Andrew R

    arr = [0,1,,,];
    alert(arr.length); // 5 (Trident), 4 (Gecko)

    Как видите, у массива есть свойство с именем/индексом ‘0’ и с именем/индексом ‘1’, других свойств нет, и длина массива отличается от максимального индекса больше, чем на единицу. Даже несмотря на различие в реализации этого дела в разных движках. Так что можно говорить только о том, что свойство length всегда больше любого индекса или равно нулю…

    комментарий от Zeroglif — Октябрь 8, 2006 @ 12:11 дп

  5. Нет такого понятие, как количество методов объекта. Смысла в том, что вы знаете, сколько у объекта методов — никакого.

    delete() — удаляет метод объекта.

    Я могу только предположить. Объект Array имеет два представления: хеш и объект с методами. В случае delete: объект array читается, как объект с методами, а в случае с splice — работа идет с хешем. Еще раз повторюсь, что это предположение и оно может быть ошибочным.

    В принципе, мне как программисту высокоуровнего языка — это и не надо знать, хотя и не помешало бы.;)))

    комментарий от 4matic — Октябрь 13, 2006 @ 12:30 дп

  6. 2 Zeroglif

    не совсем верно.

    arr = [0,1,,,]; — создаёт массив с четырмя индексами и четырмя значениями.
    0 => 0,
    1 => 1,
    2 => ,(пусто)
    3 => ,(пусто)

    таким образом, Andrew R прав.

    комментарий от andrey — Июль 6, 2007 @ 11:11 дп

  7. andrey,

    В javascript нет значений «пусто», и если вы используете «пропуск» (elision) в инициализаторе массива, то такой пропуск влияет только на одно единственное свойство массива — его длину (length) и ни на что больше. Для пропусков (elisions) вообще не создаются свойства (индексы), а значит они и не наполняются значениями (как можно дать значение несуществующему свойству).

    Вместе с Andrew R😉 вы можете легко это дело проверить (только проверяйте не в Gecko, где значения undefined ошибочно будут созданы, это баг (260106), идущий вразрез с ECMAScript).

    Удачи.

    комментарий от Zeroglif — Июль 12, 2007 @ 10:15 пп

  8. Добавлю от себя, что по массиву проходить с помощью for(var i in…) некорректно. Тем более, что в реалии это может быть коллекция (HTML-объект).

    комментарий от Петров — Сентябрь 26, 2007 @ 11:29 пп

  9. По-моему имеет место путаница. Есть массивы, нумеруемые от 0 до length-1, без пропусков, и для них вполне годится метод splice, а обход делается в арифметическом цикле.
    А есть хэши(ассоциативные массивы), являющиеся обыкновенными объектами, свойство length для которых рассматривать несколько некорректно. И для них используется delete, а обход делается через for (property in object) { /* работа с object.property или object[property] */ }

    комментарий от Shcoder — Февраль 20, 2009 @ 11:31 дп

  10. Да, и в массивах вида [0,1,,,] нет пропусков. Пустая строка — это тоже значение.

    комментарий от Shcoder — Февраль 20, 2009 @ 11:33 дп

  11. 2Shcoder

    Пустая строка — это само собой значение, но пропущенные элементы в массиве — это не пустая строка (empty string), а пропуск (elision). В соответствии со стандартом при пропуске новое свойство не создаётся, а нет свойства — не значения.

    комментарий от Zeroglif — Февраль 26, 2009 @ 10:21 дп

  12. Слишком мало тут «TFM» чтобы еще его «R» .

    my_array.splice ( what_we_want_delete , 1);

    Всё!

    комментарий от alexr — Август 5, 2010 @ 7:23 дп

  13. Мне помогла jquery, а точнее функция each :
    $.each(array, function(i, val){
    if(this.category == id) {
    this.setMap(null);
    array= array.slice(i,1);
    }
    });

    Где «i» — порядковый номер, присвоенный функцией элементу ассоциативного элемента.

    комментарий от Евг — Декабрь 18, 2012 @ 1:04 дп


RSS feed for comments on this post. TrackBack URI

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

Блог на WordPress.com.

%d такие блоггеры, как: