Как я могу предотвратить создание дополнительных элементов массива в Javascript? - PullRequest
3 голосов
/ 22 февраля 2012

В PHP, если вы сделаете это

$var = array(); 
$var[5000] = 1;
echo count($var);

Он печатает 1.

В JS он делает «недостающие» элементы.

<script type="text/javascript">
    var fred = [];
    fred[10] = 1;
    alert(fred.length);
</script>

Оповещения "11".

Могу ли я предотвратить это? Это хорошо для чего-нибудь? Я PHP-кодер, пытающийся адаптироваться к Javascript.

EDIT:

Я работаю над приложением, которое использует Google Maps v2 и markerManager. Код работал целую вечность, но проблема внезапно возникла в Chrome (17.0.963.56 м), где маркеры, кажется, дублируются (или более), а затем рендеринг перемещенных маркеров происходит совершенно неправильно, часто за этим следует зависание браузера. Просматривая DOM с использованием Firebug, я обнаружил миллиарды «неопределенных» элементов в массивах под переменной grid_ в markerManager. Я подумал, что, если бы я мог удалить их, у меня мог бы быть более приятный код, независимо от того, исправляет ли он проблему с маркером или нет. Спасибо.

Ответы [ 2 ]

1 голос
/ 22 февраля 2012

Как PHP-кодер, вы привыкли к тому, что ключи массивов довольно произвольны.В JavaScript, однако, если вы присвоите элемент массива численно, который не существует, массив будет выделен с пустыми элементами вплоть до того, который вы создали.Это поведение, которое вы нашли.С другой стороны, объекты, обозначенные {}, а не [], принимают произвольные имена свойств (с осторожностью) и функционируют немного ближе к тому, как вы привыкли функционировать структуры массива PHP.Это не означает, что объекты JavaScript (или литералы объектов) являются прямым аналогом массивов PHP ....

Если вам нужна структура данных с ключом «10», это работадля литерала объекта (хотя это не очень хорошая практика именовать свойства объекта численно.

var fred = {};
fred["10"] = 1;

Обратите внимание, что более нормальный синтаксис работы с литералом объекта - это нотация object.property, но это не так.допустимо для числовых свойств:

// name as a property
fred.name = "fred";

// Syntax error...
fred.10 = 10;

// Use [] notation for numeric properties:
fred["10"] = 10;

У литералов объекта, однако, нет свойства length, поэтому вы не можете сделать:

fred.length;
// undefined
0 голосов
/ 22 февраля 2012

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

<script type="text/javascript">
    var fred = {};
    fred['10'] = 1;
    // alert(fred.length);  // won't work anymore
</script>

С другой стороны, никакие дополнительные записи не будут генерироваться, и доступ к определенному значению работает почти так же, как в массиве. Если вы хотите просмотреть все значения, используйте следующее:

for( var el in fred ) {
  if ( fred.hasOwnProperty( el ) ) {
    alert( fred[ el ] );
  }
}
...