Подтвердить что ты не робот

Зачем задавать JavaScript-массив?

Firebug представляет (new Array(N)) как массив с N undefined в нем. Недавно я столкнулся с сценарием, который показал, что размерный массив со всеми значениями undefined в нем отличается от нового сконструированного массива размера. Я хотел бы понять разницу.

Предположим, вы хотите сгенерировать список случайных чисел от 0 до 1000.

function kilorange() {
    return Math.floor(Math.random() * (1001));
}

no_random_numbers = (new Array(6)).map(kilorange);
my_random_numbers = [undefined, undefined, undefined,
                     undefined, undefined, undefined].map(kilorange);

Я бы ожидал, что no_random_numbers и my_random_numbers будут эквивалентными, но это не так. no_random_numbers - это еще один массив из undefined s, тогда как my_random_numbers - массив с шестью случайными целыми числами. Кроме того, после того, как вы сбросили инструкцию console.count в kilorange, я узнал, что моя функция никогда не вызывается для массива, созданного с помощью конструктора Array.

В чем разница и почему map (и, предположительно, другие итерационные методы) не обрабатывают вышеуказанные массивы одинаково?

4b9b3361

Ответ 1

стандарт ES (15.4.4.19) определяет алгоритм для map, и на шаге 8b совершенно ясно, что, поскольку ваш массив фактически не имеет из этих элементов он вернет "пустой" массив длиной 6.

Как отмечали другие, он имеет отношение к объектам массива в js, которые (в отличие от их жестких C-аналогов) очень динамичны и потенциально разрежены (см. 15.4 для алгоритма проверки разреженности).

Ответ 2

При использовании:

var a = new Array(N);

никакие значения не хранятся в новом массиве, и даже индексы "свойства" не создаются. Вот почему map не будет делать ничего в этом массиве.

Тот факт, что Firebug делает это, является ошибкой/особенностью Firebug. Вы должны помнить, что консоль - это конверт eval. В консоли Firebug есть другие ошибки/функции.

Например, в консоли Chrome вы увидите приведенный выше массив a как [].

Ответ 3

Посмотрите на этот образец и запустите его: http://jsfiddle.net/ArtPD/1/ (он создает два массива без использования map над ними, а затем список ключ/значения каждого из них)

Я бы сказал, что (new Array(6)) не выделяет свойства "named" (поэтому он не создает "1": undefined, "2": undefined...), а другая форма [undefined, ... ] делает.

Фактически, если я использую for (var i in ... ), два выхода:

no_random_numbers


my_random_numbers
0 undefined
1 undefined
2 undefined
3 undefined
4 undefined
5 undefined

Ответ 4

Хороший вопрос, хорошие ответы. Я немного протолкнул прототип map из MDN. Если он будет таким образом адаптироваться, map будет работать для new Array([length])
Array.prototype.map = function(callback, thisArg) {
    var T, A, k;
    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }
    var O = Object(this);
    var len = O.length >>> 0;
    if ({}.toString.call(callback) != "[object Function]") {
      throw new TypeError(callback + " is not a function");
    }
    if (thisArg) {
      T = thisArg;
    }
    A = new Array(len);
    k = 0;
    while(k < len) {
      var kValue, mappedValue;
      if (k in O || (O.length && !O[k])) {
//                  ^ added this
        kValue = O[ k ];
        mappedValue = callback.call(T, kValue, k, O);
        A[ k ] = mappedValue;
      }
      k++;
    }
    return A;
};

На основе ответа Casy Hopes вы также можете сделать mapx -extension, чтобы иметь возможность использовать map с некоторыми new Array([length]):

Array.prototype.mapx = function(callback){
  return this.join(',').split(',').map(callback);
}
//usage
var no_random_numbers = new Array(6).mapx(kilorange);

Ответ 5

Чтобы ответить на вопрос заголовка (почему массивы presize), единственное, что я использовал для инициализации массива Array(n), - это создать строку длины n-1:

var x = Array(6).join('-'); // "-----"

Ответ 6

Чтобы ответить на вопрос, почему вы назначили массив, вы сделаете так, чтобы вам не приходилось делать столько индивидуальных распределений. Выделение памяти занимает некоторое время, и это может вызвать запуск сборки мусора, который может занять много времени.

На типичной веб-странице вы не заметите разницы, но если вы делаете что-то важное, это может помочь честно.