Использование JavaScript новой декларации Array (n) - PullRequest
48 голосов
/ 07 августа 2009

Простой вопрос JavaScript: поскольку для массивов нет жесткого ограничения, как в случае с Java (т. Е. IndexOutOfBoundsException ), для чего используется объявление, в котором мы указываем свойство длины?

var a = new Array(10);

Я знаю, что это предопределяет длину и помещает "неопределенный" в эти пустые места. Достаточно ли этой причины для этого?

Ответы [ 8 ]

40 голосов
/ 08 августа 2009

Существует много очевидных преимуществ объявления размера массива, но я думаю, что большинство предполагаемых преимуществ - просто FUD, передаваемый.

Лучшая производительность! / Это быстрее!

Насколько я могу судить, разница между предварительным и динамическим распределением ничтожна.

Что еще интереснее, спецификация не заявляет, что массив должен быть установлен на заранее выделенную длину!

Из раздела 15.4.2.2 ECMA-262 :

Если аргумент len является Number и ToUint32 ( len ) равен len , то свойство length объекта Вновь созданный объект имеет значение ToUint32 ( len ). Если аргумент len является числом и ToUint32 ( len ) не равен len , возникает исключение RangeError .

Ненаучный забавный тестовый пример здесь: http://jsbin.com/izini

Это делает код более понятным!

Лично я не согласен.

Рассмотрите JavaScript, который вы написали в прошлом, и рассмотрите код, который вам, возможно, придется написать в будущем. Я не могу вспомнить ни одного момента, когда мне нужно было указать статический предел для одного из моих массивов. Я также утверждаю, что потенциальные проблемы ограничения массивов в javascript значительно перевешивают преимущества, которые дает людям знать, о чем вы думаете, без каких-либо реальных проверок. Давайте взвесить все за и против ...

Плюсы:

  1. Им будет легче понять, для чего предназначен код.
  2. Позже они смогут найти ошибки, вызванные вашим предположением (язык твердо в щеке)

Минусы:

  1. Быстрые взгляды могут легко спутать «new Array (10)» с «new Array ('10 ')», которые делают совершенно разные вещи!
  2. Вы накладываете произвольное ограничение на код без нормального ограничения длины, что заставляет вас писать множество кодов котельной пластины для проверки и поддержания ограничения.
  3. Вы накладываете произвольное ограничение на код, который, вероятно, можно было бы обобщить для работы с любой длиной значений.
  4. Вы делаете предположение о том, как люди будут читать ваш код, предполагая, что альтернатива будет менее запутанной.

Вы также можете написать:

//I assume this array will always be length 10
var arr = new Array();

В приведенном выше случае комментарий может быть даже предпочтительнее. Явное объявление намерения может избежать любой путаницы, к которой не привык использовать конструктор в качестве объявления намерения.

Хорошо, тогда ... почему вы думаете, что это даже там тогда?

Удобство. Когда они писали спецификации, я думаю, что они поняли две вещи.

  1. Для такого рода заданий будут использоваться разработчики из похожих языков.
  2. Реализации ECMAScript потенциально могут использовать его для повышения производительности.

Так что они положили его туда. Спецификация определяет только использование параметра, а не то, как он должен быть реализован.

26 голосов
/ 03 июля 2012

Производительность на движке V8 JavaScript.

Делая:

var arr = []; arr.length = 1000;

V8 будет предварительно выделять требуемую память для массива и поддерживать / устанавливать для Hidden Class массива compact SMI (Small Int, 31 бит без знака) array . Однако это не так, когда желаемая длина слишком велика, что приводит к тому, что для HC установлено значение разреженный массив (т.е. карта).

Попробуйте следующую ссылку в Chrome: http://jsperf.com/0-fill-n-size-array

Я включил дополнительный тестовый пример без определения длины массива, чтобы вы могли определить реальную разницу в производительности.

Информация, связанная с данной: http://www.youtube.com/watch?v=UJPdhx5zTaw

7 голосов
/ 07 августа 2009

Clarity.

При написании кода ваша цель - не , чтобы компьютер понимал вас, а для следующего программиста, который читает ваш код, чтобы понять вас.

var xs = new Array(10);

Приведенный выше код показывает ваше намерение : иметь массив из 10 элементов.

var xs = [];

Вышесказанное ничего не дает; без дополнительной информации.

Приветствие.

6 голосов
/ 07 августа 2009

Я не уверен, но я бы поспорил, что он выделяет память по-другому на низком уровне. Если вы знаете, что создаете 10000 элементов, просто зарезервируйте столько места, а не динамически изменяйте его размер в фоновом режиме.

2 голосов
/ 06 декабря 2017

Предположим, вам нужен массив определенной длины, инициализированный определенным значением. Это не будет работать:

scores = [].fill(0.0, 0, studentCount);

Это просто даст вам пустой массив, потому что fill () никогда не расширит массив за его первоначальную длину.

Это будет работать:

scores = new Array(studentCount).fill(0.0, 0, studentCount);

Это даст вам массив значений studentCount, инициализированных в ноль.

2 голосов
/ 07 августа 2015

Я создал этот JSPerf , который демонстрирует проблему, включая ее различные версии. Аргументы, которые я нахожу, такие:

  1. Использование new Array () может вести себя неожиданно, может быть переопределено
  2. Установка .length фактически не увеличивает размер массива в некоторых браузерах
  3. Хита производительности на самом деле нет.

Я думаю, что эти тесты должны уложить эти аргументы, но следует отметить, что разные браузеры решают эту проблему по-разному. Firefox, похоже, оптимизирует и выясняет, насколько большим будет массив , равный , в то время как Chrome выделяет память, как и следовало ожидать. И, как обычно, Internet Explorer просто воняет от этой задачи.

0 голосов
/ 01 ноября 2015

Не сложно поддерживать размер массива. Посмотрите на следующий пример:

function updateArray(){
    var a = [1,2,3,4,5,6,7,8,9,10]; //original array object
    var b = [11, 12, 13];  //New array object to be pushed
    a.splice(a.length-b.length, a.length);
    a.unshift.apply(a, b);
    return a;
}

a.unshift.apply(arg1, arg2) нажмите новый элемент сверху и a.push.apply(arg1, arg2) снизу.

0 голосов
/ 11 сентября 2012

Ну лично я хочу очередь. Я хочу, чтобы очередь была длиной 10.

Самый простой способ сделать это - использовать метод массива push, чтобы поместить элементы в конец очереди, и метод shift(), чтобы убрать их с начала массива.

Проблема в том, что если я хочу сделать простой метод «добавить» в мою очередь, и я пишу это так:

function addItemToArray(item, array){
    array.shift();
    array.push(item);
    return array;
}

тогда ничего хорошего не происходит. Что лучше (на самом деле, что будет работать), так это объявить мой массив следующим образом:

var maxSizeIsTen = new Array(10);

, а затем используйте его везде. Также обратите внимание на «хороший» способ описания массива - никаких комментариев, которые никто не читает, и любой, кто использует этот код, в кратчайшие сроки определит максимальный размер этого массива.

YAY!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...