В чем разница между "Array()" и "[]" при объявлении массива JavaScript?

В чем реальная разница между объявлением массива следующим образом:

var myArray = new Array();

а также

var myArray = [];

20 ответов

Решение

Есть разница, но в этом примере нет никакой разницы.

Используя более подробный метод: new Array() есть одна дополнительная опция в параметрах: если вы передадите число конструктору, вы получите массив такой длины:

x = new Array(5);
alert(x.length); // 5

Чтобы проиллюстрировать различные способы создания массива:

var a = [],            // these are the same
    b = new Array(),   // a and b are arrays with length 0

    c = ['foo', 'bar'],           // these are the same
    d = new Array('foo', 'bar'),  // c and d are arrays with 2 strings

    // these are different:
    e = [3]             // e.length == 1, e[0] == 3
    f = new Array(3),   // f.length == 3, f[0] == undefined

;

Разница между созданием массива с неявным массивом и конструктором массива неощутима, но важна.

Когда вы создаете массив с помощью

var a = [];

Вы говорите интерпретатору создать новый массив времени выполнения. Никакой дополнительной обработки не требуется вообще. Готово.

Если вы используете:

var a = new Array();

Вы говорите переводчику, я хочу вызвать конструкторArray"и сгенерировать объект. Затем он просматривает ваш контекст выполнения, чтобы найти конструктор для вызова, и вызывает его, создавая ваш массив.

Вы можете подумать: "Ну, это совсем не важно. Они одинаковые!". К сожалению, вы не можете гарантировать это.

Возьмите следующий пример:

function Array() {
    this.is = 'SPARTA';
}

var a = new Array();
var b = [];

alert(a.is);  // => 'SPARTA'
alert(b.is);  // => undefined
a.push('Woa'); // => TypeError: a.push is not a function
b.push('Woa'); // => 1 (OK)

В приведенном выше примере, первый звонок предупредит 'SPARTA', как и следовало ожидать. Второго не будет. В итоге вы увидите неопределенное. Вы также заметите, что b содержит все функции объекта Array, такие как pushгде другой нет.

Хотя вы можете ожидать, что это произойдет, это просто иллюстрирует тот факт, что [] это не то же самое, что new Array(),

Это, вероятно, лучше всего использовать [] если вы знаете, что вы просто хотите массив. Я также не предлагаю обходить и переопределять Array...

Существует огромная разница, о которой никто не упоминал.

Вы можете подумать new Array(2) эквивалентно [undefined, undefined] раньше, потому что у нас есть

new Array(2).length           // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true

НО ЭТОГО НЕТ!

Давай попробуем map():

[undefined, undefined].map(e => 1)  // [1, 1]
new Array(2).map(e => 1)            // "(2) [undefined × 2]" in Chrome

Увидеть? Это другое! Но почему это?

Согласно ES6 Spec 22.1.1.2, Array(len) только создает новый массив с length установлен в len и больше ничего. Таким образом, внутри нового массива нет реального элемента.

Пока функция map()в соответствии со спецификацией 22.1.3.15 сначала проверит HasProperty затем вызвать обратный вызов, но получается, что:

new Array(2).hasOwnProperty(0) // false
[undefined, undefined].hasOwnProperty(0) // true

Поэтому нельзя ожидать, что какие-либо итерационные функции будут работать как обычно с массивом, созданным изnew Array(len),

Кстати, Safari и Firefox имеют гораздо лучшее выражение для этого:

// Safari
new Array(2)             // [](2)
new Array(2).map(e => 1) // [](2) 
[undefined, undefined]   // [undefined, undefined] (2) 

// Firefox
new Array(2)             // Array [ <2 empty slots> ]
new Array(2).map(e => 1) // Array [ <2 empty slots> ]
[undefined, undefined]   // Array [ undefined, undefined ]

Я уже отправил вопрос в Chrome, чтобы попросить их исправить этот запутанный журнал: https://bugs.chromium.org/p/chromium/issues/detail?id=732021

ОБНОВЛЕНИЕ: Это уже исправлено. Chrome теперь войти как

new Array(2)             // (2) [empty × 2]

Довольно странно, new Array(size) почти в 2 раза быстрее, чем [] в Chrome и примерно одинаково в FF и IE (измеряется путем создания и заполнения массива). Это имеет значение, только если вы знаете приблизительный размер массива. Если вы добавите больше элементов, чем указали длину, повышение производительности будет потеряно.

Точнее: Array( это быстрая операция с постоянным временем, которая не выделяет память, когда [] является линейной операцией времени, которая устанавливает тип и значение.

Для получения дополнительной информации на следующей странице описано, почему вам никогда не нужно использовать new Array()

Вам никогда не нужно использовать new Object() в JavaScript. Используйте литерал объекта {} вместо. Точно так же не используйте new Array(), используйте массив литерал [] вместо. Массивы в JavaScript не работают так же, как массивы в Java, и использование Java-подобного синтаксиса вас смущает.

Не использовать new Number, new String, или же new Boolean, Эти формы создают ненужные обертки объектов. Просто используйте простые литералы вместо этого.

Также проверьте комментарии - new Array(length) Форма не служит какой-либо полезной цели (по крайней мере, в современных реализациях JavaScript).

Чтобы лучше понять [] а также new Array():

> []
  []
> new Array()
  []
> [] == []
  false
> [] === []
  false
> new Array() == new Array()
  false
> new Array() === new Array()
  false
> typeof ([])
  "object"
> typeof (new Array())
  "object"
> [] === new Array()
  false
> [] == new Array()
  false

Вышеуказанный результат получен из консоли Google Chrome в Windows 7.

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

var array = new Array(5); //initialize with default length 5

Второй дает вам возможность создавать не пустой массив:

var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.

Я могу объяснить более конкретно, начиная с этого примера, основанного на хорошем примере Фредрика.

var test1 = [];
test1.push("value");
test1.push("value2");

var test2 = new Array();
test2.push("value");
test2.push("value2");

alert(test1);
alert(test2);
alert(test1 == test2);
alert(test1.value == test2.value);

Я просто добавил еще одно значение в массивы и сделал четыре предупреждения: первое и второе - дать нам значение, хранящееся в каждом массиве, чтобы быть уверенным в значениях. Они вернутся так же! Теперь попробуйте третий, он возвращает ложь, потому что

JS рассматривает test1 как переменный с типом данных массива, и он рассматривает test2 как ОБЪЕКТ с функциональностью массива, и здесь есть несколько небольших различий.

Первое различие заключается в том, что когда мы вызываем test1, он вызывает переменную, не задумываясь, он просто возвращает значения, которые хранятся в этой переменной, независимо от ее типа данных! Но когда мы вызываем test2, он вызывает функцию Array(), а затем сохраняет наши значения "Pressed" в свойстве "Value", и то же самое происходит, когда мы предупреждаем test2, он возвращает свойство "Value" объекта массива.

Поэтому, когда мы проверяем, равен ли test1 равен test2, они, конечно, никогда не вернут true, один - функция, а другой - переменная (с типом массива), даже если они имеют одинаковое значение!

Чтобы быть уверенным в этом, попробуйте 4-е предупреждение с добавленным.value; это вернет истину. В этом случае мы сообщаем JS "Независимо от типа контейнера, будь то функция или переменная, сравните значения, хранящиеся в каждом контейнере, и скажите нам, что вы видели!" это именно то, что происходит.

Надеюсь, я четко сформулировал эту идею, и извините за мой плохой английский.

Это больше, чем кажется на первый взгляд. Большинство других ответов верны, НО ТАКЖЕ..

new Array(n)

  • Позволяет движку перераспределять пространство для n элементы
  • Оптимизирован для создания массивов
  • Созданный массив помечается как разреженный, который имеет наименее производительные операции с массивом, потому что каждый доступ к индексу должен проверять границы, видеть, существует ли значение, и проходить цепочку прототипов
  • Если массив отмечен как разреженный, пути назад нет (по крайней мере, в V8), он всегда будет медленнее в течение своего времени жизни, даже если вы заполните его содержимым (упакованный массив) через 1 мс или 2 часа, не имеет значения

[1, 2, 3] || []

  • Созданный массив помечается как упакованный (если вы не используетеdelete или [1,,3] синтаксис)
  • Оптимизирован для операций с массивами (for .., forEach, map, так далее)
  • Движку необходимо перераспределять пространство по мере роста массива

Это, вероятно, это не так для старых браузеров версий / браузеров.

Нет разницы, когда вы инициализируете массив без какой-либо длины. Так var a = [] & var b = new Array() такой же.

Но если вы инициализируете массив с длиной, как var b = new Array(1);, он установит длину объекта массива в 1. Таким образом, его эквивалент var b = []; b.length=1;,

Это будет проблематично всякий раз, когда вы делаете array_object.push, он добавляет элемент после последнего элемента и увеличивает длину.

var b = new Array(1);
b.push("hello world");
console.log(b.length); // print 2

против

var v = [];
a.push("hello world");
console.log(b.length); // print 1

Большой разницы нет, они в основном делают одно и то же, но делают это по-разному, но читайте дальше, посмотрите на это утверждение на W3C:

var cars = ["Saab", "Volvo","BMW"];

а также

var cars = new Array("Saab", "Volvo", "BMW");

Два приведенных выше примера делают то же самое. Нет необходимости использовать новый Array().
Для простоты, читабельности и скорости выполнения используйте первый (метод литерала массива).

Но в то же время, создание нового массива с использованием new Array Синтаксис считается плохой практикой:

Избегайте нового массива ()

Нет необходимости использовать встроенный в JavaScript конструктор массива new Array().
Используйте вместо этого [].
Эти два разных оператора создают новый пустой массив с именем points:

var points = new Array();         // Bad
var points = [];                  // Good 

Эти два разных оператора создают новый массив, содержащий 6 чисел:

var points = new Array(40, 100, 1, 5, 25, 10); // Bad    
var points = [40, 100, 1, 5, 25, 10];          // Good

Новое ключевое слово только усложняет код. Это также может привести к неожиданным результатам:

var points = new Array(40, 100);  // Creates an array with two elements (40 and 100)

Что если я удалю один из элементов?

var points = new Array(40);       // Creates an array with 40 undefined elements !!!!!

Таким образом, в принципе не считается лучшей практикой, также есть одно небольшое отличие, вы можете передать длину new Array(length) как это, что также не рекомендуется.

Первый - это конструктор объекта по умолчанию call.most, используемый для динамических значений.

var array = new Array(length); //initialize with default length

второй массив используется при создании статических значений

var array = [red, green, blue, yellow, white]; // this array will contain values.

Хорошо, var x = new Array() отличается от var x = [] отличается некоторыми функциями. Я просто объясню две наиболее полезных (на мой взгляд) из них.

Прежде чем я перейду к объяснению различий, я сначала установлю основу; когда мы используемx = []определяет новую переменную с типом данных Array и наследует все методы, принадлежащие прототипу массива, что-то очень похожее (но не в точности) на расширение класса. Однако, когда мы используемx = new Array() он инициирует клонирование прототипа массива, присвоенного переменной x.

Теперь посмотрим, в чем разница

Первое отличие заключается в том, что использованиеnew Array(x) где x является целым числом, инициализирует массив x неопределенные значения, например new Array(16)инициализирует массив с 16 элементами, все они не определены. Это очень полезно, когда вы асинхронно заполняете массив заранее определенной длины. Например (снова:)) предположим, что вы получаете результаты 100 конкурентов, и вы получаете их асинхронно из удаленной системы или базы данных, тогда вам нужно будет распределить их в массиве в соответствии с рангом, как только вы получите каждый результат. В этом очень редком случае вы сделаете что-то вродеmyArray[result.rank - 1] = result.name, поэтому ранг 1 будет установлен на индекс 0 и так далее.

Второе отличие заключается в том, что использованиеnew Array()как вы уже знаете, создает новый клон прототипа массива и назначает его вашей переменной, что позволяет вам творить чудеса (кстати, не рекомендуется). Эта магия заключается в том, что вы можете перезаписать определенный метод устаревших методов массива. Так, например, вы можете установитьArray.push, чтобы поместить новое значение в начало массива, а не в конец, и вы также можете добавить новые методы (это лучше) к этому конкретному клону прототипа массива. Это позволит вам определять более сложные типы массивов в вашем проекте с вашими собственными добавленными методами и использовать их как класс.

И последнее: если вы из очень немногих людей (которых я действительно люблю), которые заботятся об издержках обработки и потреблении памяти вашим приложением, вам никогда не придется new Array() не отчаявшись использовать его:).

Я надеюсь, что достаточно объяснил про зверя new Array():)

Как я знаю, различие вы можете найти срез (или другие функции массива), такие как code1. И code2 показывают u Array и его экземпляры:

code1:

[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here

code2:

[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true

заключение:

как ты можешь видеть [] а также new Array() создайте новый экземпляр Array. И все они получают функции-прототипы из Array.prototype

Они просто разные экземпляры Array.так это объясняет почему[] != []

:)

Я столкнулся со странным поведением, используя [].

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

require([
  "dojo/_base/declare",
  "dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){

   declare("MyWidget", [_WidgetBase], {
     field1: [],
     field2: "",
     function1: function(),
     function2: function()
   });    
});

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

Этого не происходит, инициализируя их new Array(), То же самое для инициализации объектов ({} против нового Object())

TBH Я не уверен, если это проблема с фреймворком, который мы использовали ( Dojo)

Разница в использовании

var arr = new Array(size);

Или же

arr = [];
arr.length = size;

Как достаточно обсуждалось в этом вопросе.

Я хотел бы добавить проблему скорости - текущий самый быстрый способ, на google chrome это второй.

Но обратите внимание, эти вещи, как правило, сильно меняются с обновлениями. Также время выполнения будет отличаться в разных браузерах.

Например - второй вариант, который я упомянул, работает со скоростью 2 миллиона [операций в секунду] на chrome, но если вы попробуете это на mozilla dev. Вы получите удивительно высокий показатель в 23 миллиона.

В любом случае, я бы посоветовал вам проверять это время от времени на разных браузерах (и машинах), используя сайт как таковой.

Иметь ввиду:

Работайте с новым или пропускайте его, на работу кода это не повлияет.

Рассмотрим этот пример:

  • Еще одним преимуществом использования этого метода является то, что он заранее создает в стеке массив необходимого размера.

Причина не использовать: Новое

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

Надеюсь, поможет.

Я нашел разницу при использовании обещаний. При использовании массива промисов (скажем, arr, инициализированного как arr=[]) возникла ошибка в Promise.all(arr). В то время как при объявлении как arr = Array() проблем с компиляцией не возникало. Надеюсь это поможет.

Я обнаружил одно различие между двумя конструкциями, которое меня сильно укусило.

Допустим, у меня есть:

function MyClass(){
  this.property1=[];
  this.property2=new Array();
};
var MyObject1=new MyClass();
var MyObject2=new MyClass();

В реальной жизни, если я делаю это:

MyObject1.property1.push('a');
MyObject1.property2.push('b');
MyObject2.property1.push('c');
MyObject2.property2.push('d');

В итоге я получаю вот что:

MyObject1.property1=['a','c']
MyObject1.property2=['b']
MyObject2.property1=['a','c']
MyObject2.property2=['d']

Я не знаю, что должно произойти в спецификации языка, но если я хочу, чтобы мои два объекта имели уникальные массивы свойств в своих объектах, я должен использовать new Array(),

Использование конструктора Array создает новый массив требуемой длины и заполняет каждый из индексов неопределенным, а присвоенный массив переменной создает индексы, для которых вы предоставляете ему информацию.

Другие вопросы по тегам