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