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

StackOverflow https://stackoverflow.com/questions/931872

  •  06-09-2019
  •  | 
  •  

Вопрос

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

var myArray = new Array();

и

var myArray = [];
Это было полезно?

Решение

Разница есть, но в этом примере ее нет.

Используя более подробный метод: 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

;

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

Как указано в этот ответ, new Array(5) на самом деле не прибавит пять undefined элементы в массив.Это просто добавляет место для пяти предметов.Имейте в виду, что использование Array таким образом, на него трудно положиться array.length для расчетов.

Другие советы

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

Когда вы создаете массив, используя

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)

В приведенном выше примере первый вызов предупредит «Спарту», ​​как и следовало ожидать.Второго не будет.В конечном итоге вы увидите неопределенное.Вы также заметите, что 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) form не служит никакой полезной цели (по крайней мере, в современных реализациях 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);

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

JS лечит тест1 как ПЕРЕМЕННАЯ с типом данных массива, и это лечит тест2 как ОБЪЕКТ с функциональностью массива, и здесь есть несколько незначительных отличий.

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

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

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

Надеюсь, я ясно выразил идею, и прошу прощения за мой плохой английский.

Нет никакой разницы, когда вы инициализируете массив без какой-либо длины.Так 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

Первый — это вызов конструктора объекта по умолчанию. Чаще всего он используется для динамических значений.

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

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

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

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

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

и

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

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

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

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

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

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) вот так, что тоже не рекомендуется.

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

var arr = new Array(size);

Или

arr = [];
arr.length = size;

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

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

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

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

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

Насколько я знаю разницу, вы можете найти срез (или другие функции массива), например код1код2 покажу тебе Множество и его случаи:

код1:

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

код2:

[].__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()
   });    
});

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

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

Честно говоря, я не уверен, что это проблема с используемой нами структурой (Додзё)

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

Скажем, у меня есть:

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 создает новый массив желаемой длины и заполняет каждый из индексов неопределенным значением, присвоенный массив переменной создает индексы, для которых вы предоставляете ему информацию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top