Jaka jest prawdziwa różnica między deklarowaniem tablicy takiej jak ta:
var myArray = new Array();
i
var myArray = [];
Jaka jest prawdziwa różnica między deklarowaniem tablicy takiej jak ta:
var myArray = new Array();
i
var myArray = [];
Odpowiedzi:
Jest różnica, ale w tym przykładzie nie ma różnicy.
Używając bardziej szczegółowej metody: new Array()
ma jedną dodatkową opcję w parametrach: jeśli przekażesz liczbę do konstruktora, otrzymasz tablicę o tej długości:
x = new Array(5);
alert(x.length); // 5
Aby zilustrować różne sposoby tworzenia tablicy:
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
;
Kolejna różnica polega na tym, że podczas używania new Array()
możesz ustawić rozmiar tablicy, co wpływa na rozmiar stosu. Może to być przydatne, jeśli występują przepełnienia stosu ( Wydajność Array.push vs. Array.unshift ), co dzieje się, gdy rozmiar tablicy przekracza rozmiar stosu i należy go ponownie utworzyć. Tak więc, w zależności od przypadku użycia, może wystąpić wzrost wydajności, new Array()
ponieważ można zapobiec przepełnieniu.
Jak wskazano w tej odpowiedzi , new Array(5)
tak naprawdę nie doda pięciu undefined
elementów do tablicy. Po prostu dodaje miejsce na pięć przedmiotów. Należy pamiętać, że korzystanie z Array
tej metody utrudnia poleganie na array.length
obliczeniach.
Różnica między tworzeniem tablicy za pomocą tablicy niejawnej a konstruktorem tablicy jest subtelna, ale ważna.
Podczas tworzenia tablicy za pomocą
var a = [];
Mówisz tłumaczowi, aby utworzył nową tablicę wykonawczą. Żadne dodatkowe przetwarzanie w ogóle nie jest konieczne. Gotowy.
Jeśli użyjesz:
var a = new Array();
Mówisz tłumaczowi, że chcę wywołać konstruktor Array
i wygenerować obiekt. Następnie przegląda kontekst wykonania, aby znaleźć konstruktora do wywołania, i wywołuje go, tworząc tablicę.
Możesz pomyśleć: „Cóż, to wcale nie ma znaczenia. Są takie same!”. Niestety nie możesz tego zagwarantować.
Weź następujący przykład:
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)
W powyższym przykładzie pierwsze połączenie ostrzeże „SPARTA”, jak można się spodziewać. Drugi nie. Skończysz na niezdefiniowanym. Zauważysz również, że b zawiera wszystkie natywne funkcje obiektu Array, takie jak push
, gdzie inne nie.
Chociaż możesz się spodziewać, że tak się stanie, to po prostu ilustruje fakt, że []
to nie to samo, co new Array()
.
Prawdopodobnie najlepiej jest po prostu użyć, []
jeśli wiesz, że chcesz tylko tablicę. Nie sugeruję też chodzenia i redefiniowania Array ...
Istnieje ważna różnica, o której jeszcze nie wspomniano w żadnej odpowiedzi.
Od tego:
new Array(2).length // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true
Możesz myśleć, że to new Array(2)
jest równoważne [undefined, undefined]
, ale NIE jest!
Spróbujmy z map()
:
[undefined, undefined].map(e => 1) // [1, 1]
new Array(2).map(e => 1) // "(2) [undefined × 2]" in Chrome
Widzieć? Semantyka jest zupełnie inna! Dlaczego tak jest?
Zgodnie z ES6 Spec 22.1.1.2, zadaniem Array(len)
jest po prostu tworzenie nowej tablicy, której właściwość length
jest ustawiona na argument len
i to wszystko, co oznacza, że nie ma żadnego prawdziwego elementu w tej nowo utworzonej tablicy.
Funkcja map()
, zgodnie ze specyfikacją 22.1.3.15, najpierw sprawdza, HasProperty
a następnie wywołuje oddzwonienie, ale okazuje się, że:
new Array(2).hasOwnProperty(0) // false
[undefined, undefined].hasOwnProperty(0) // true
I dlatego nie można oczekiwać, że jakiekolwiek funkcje iterujące będą działać normalnie na tablicach utworzonych znew Array(len)
.
BTW, Safari i Firefox mają znacznie lepsze „drukowanie” w tej sytuacji:
// 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 ]
Już przesłałem problem do Chromium i poprosiłem go o naprawienie tego mylącego drukowania: https://bugs.chromium.org/p/chromium/issues/detail?id=732021
AKTUALIZACJA: Jest już naprawione. Chrome jest teraz drukowany jako:
new Array(2) // (2) [empty × 2]
[...Array(2)]
co jest równoważne [undefined, undefined]
z punktu widzenia wyników.
undefined
jak zwykle.
Co dziwne, new Array(size)
jest prawie dwa razy szybszy niż []
w Chrome i mniej więcej taki sam w FF i IE (mierzony poprzez utworzenie i wypełnienie tablicy). Ma to znaczenie tylko wtedy, gdy znasz przybliżony rozmiar tablicy. Jeśli dodasz więcej elementów niż podana długość, zwiększenie wydajności zostanie utracone.
Dokładniej: Array(
jest to szybka operacja w stałym czasie, która nie przydziela pamięci, wheras []
jest liniową operacją w czasie, która ustawia typ i wartość.
new Array(length)
na 0 <= rozmiar <= ~ 1000, na rozmiar> ~ 1000 wygrywa[]
Aby uzyskać więcej informacji, na następnej stronie opisano, dlaczego nigdy nie musisz go używaćnew Array()
Nigdy nie musisz używać
new Object()
w JavaScript.{}
Zamiast tego użyj literału obiektu . Podobnie nie używajnew Array()
,[]
zamiast tego użyj literału tablicowego . Tablice w JavaScript działają podobnie jak tablice w Javie, a użycie składni podobnej do Java dezorientuje.Nie używać
new Number
,new String
lubnew Boolean
. Te formy powodują niepotrzebne zawijanie obiektów. Zamiast tego używaj prostych literałów.
Zobacz także komentarze - new Array(length)
formularz nie służy żadnemu przydatnemu celowi (przynajmniej w dzisiejszych implementacjach JavaScript).
Aby lepiej zrozumieć []
i 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
Powyższy wynik pochodzi z konsoli Google Chrome w systemie Windows 7.
Array(3)
lub new Array(3)
nie jest taki sam jak [3]
.
Pierwszy to domyślne wywołanie konstruktora obiektów. Możesz użyć jego parametrów, jeśli chcesz.
var array = new Array(5); //initialize with default length 5
Drugi daje możliwość utworzenia niepustej tablicy:
var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.
var array = [5]
za pomocą nawiasów kwadratowych, ale nie używając konstruktora, ponieważ var array = Array(5)
tworzy pustą tablicę 5 elementów.
Mogę wyjaśnić w bardziej konkretny sposób, zaczynając od tego przykładu opartego na dobrym przykładzie Fredrika.
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);
Właśnie dodałem kolejną wartość do tablic i wysłałem cztery alarmy: pierwszy i drugi mają dać nam wartość przechowywaną w każdej tablicy, aby mieć pewność co do wartości. Zwrócą to samo! Teraz wypróbuj trzeci, zwraca false, to dlatego, że
JS traktuje test1 jako ZMIENNY z typem danych tablicy , i traktuje test2 jako OBIEKT z funkcjonalnością tablicy , a tutaj jest kilka drobnych różnic.
Pierwszą różnicą jest to, że gdy wywołujemy test1, to wywołuje zmienną bez zastanowienia, po prostu zwraca wartości zapisane w tej zmiennej bez względu na jej typ danych! Ale kiedy wywołujemy test2, wywołuje on funkcję Array (), a następnie przechowuje nasze wartości „Push” we właściwości „Value” , i to samo dzieje się, gdy ostrzegamy test2, zwraca właściwość „Value” obiektu tablicy.
Kiedy więc sprawdzimy, czy test1 jest równy test2, oczywiście nigdy nie zwrócą wartości true, jedna jest funkcją, a druga zmienną (z rodzajem tablicy), nawet jeśli mają tę samą wartość!
Aby się upewnić, wypróbuj 4. alert z dodaną wartością .value; zwróci prawdę. W takim przypadku mówimy JS „Niezależnie od typu kontenera, czy był to funkcja czy zmienna, porównaj wartości przechowywane w każdym kontenerze i powiedz nam, co widziałeś!” dokładnie tak się dzieje.
Mam nadzieję, że jasno wyraziłem ten pomysł i przepraszam za mój zły angielski.
[]
i new Array()
jest identyczny; .value
będzie undefined
w obu przypadkach, a porównywanie ich zawsze będzie fałszywe.
array.value
. i oba typeof []
i typeof new Array()
powrotu object
. Jest to jeden z powodów, dla których istnieje funkcja o nazwieArray.isArray
Nie ma różnicy przy inicjalizacji tablicy bez jakiejkolwiek długości. Więc var a = []
& var b = new Array()
jest taki sam.
Ale jeśli zainicjujesz tablicę o długości podobnej var b = new Array(1);
, ustawi ona długość obiektu tablicy na 1. Więc jest to odpowiednik var b = []; b.length=1;
.
Będzie to problematyczne za każdym razem, gdy wykonasz array_object.push, dodasz element po ostatnim elemencie i zwiększysz długość.
var b = new Array(1);
b.push("hello world");
console.log(b.length); // print 2
vs
var v = [];
a.push("hello world");
console.log(b.length); // print 1
Pierwszym z nich jest domyślne wywołanie konstruktora obiektów. Używane głównie do wartości dynamicznych.
var array = new Array(length); //initialize with default length
druga tablica jest używana podczas tworzenia wartości statycznych
var array = [red, green, blue, yellow, white]; // this array will contain values.
Nie ma dużej różnicy, w zasadzie robią to samo, ale robią to na różne sposoby, ale czytaj dalej, spójrz na to oświadczenie na W3C:
var cars = ["Saab", "Volvo","BMW"];
i
var cars = new Array("Saab", "Volvo", "BMW");
Dwa powyższe przykłady robią dokładnie to samo. Nie ma potrzeby używania nowego Array ().
Dla uproszczenia, czytelności i szybkości wykonania użyj pierwszej (metoda dosłowna tablicowa).
Ale jednocześnie tworzenie nowej tablicy przy użyciu new Array
składni uważanej za złą praktykę:
Unikaj nowej macierzy ()
Nie ma potrzeby korzystania z wbudowanego w JavaScript konstruktora tablic new Array ().
Zamiast tego użyj [].
Te dwie różne instrukcje tworzą nową pustą tablicę o nazwie punkty:
var points = new Array(); // Bad
var points = []; // Good
Te dwie różne instrukcje tworzą nową tablicę zawierającą 6 liczb:
var points = new Array(40, 100, 1, 5, 25, 10); // Bad
var points = [40, 100, 1, 5, 25, 10]; // Good
Nowy kluczowe komplikuje tylko kod. Może także dawać nieoczekiwane wyniki:
var points = new Array(40, 100); // Creates an array with two elements (40 and 100)
Co się stanie, jeśli usunę jeden z elementów?
var points = new Array(40); // Creates an array with 40 undefined elements !!!!!
Więc zasadniczo nie jest uważany za najlepszą praktykę, jest też jedna drobna różnica, możesz podać długość, aby new Array(length)
to polubić, co również nie jest zalecanym sposobem.
new Array(40).fill(123)
Różnica użycia
var arr = new Array(size);
Lub
arr = [];
arr.length = size;
Jak już zostało wystarczająco omówione w tym pytaniu.
Chciałbym dodać problem prędkości - obecnie najszybszym sposobem google chrome
jest drugi.
Ale zwróć uwagę, te rzeczy często zmieniają się wraz z aktualizacjami. Również czas działania będzie różny dla różnych przeglądarek.
Na przykład - druga opcja, o której wspomniałem, działa przy 2 milionach [operacji / sekundę] chrome
, ale jeśli spróbujesz mozilla dev.
, otrzymasz zaskakująco wyższą stawkę 23 milionów.
W każdym razie sugeruję, abyś sprawdzał to, co jakiś czas, w różnych przeglądarkach (i maszynach), używając witryny jako takiej
Jak znam diference u można znaleźć kawałek (lub inne funcitons Array), jak kod1 .i code2 pokazać u Array i jego wystąpienia :
kod1:
[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here
kod2:
[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true
wniosek:
jak możesz zobaczyć []
i new Array()
utworzyć nową instancję Array. I oni wszyscy otrzymują prototypowe funkcje odArray.prototype
Są po prostu inną instancją Array. Więc to wyjaśnia dlaczego
[] != []
:)
Dziwnie się zachowałem, używając [].
Mamy „klasy” modelu z polami zainicjowanymi do pewnej wartości. Na przykład:
require([
"dojo/_base/declare",
"dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){
declare("MyWidget", [_WidgetBase], {
field1: [],
field2: "",
function1: function(),
function2: function()
});
});
Odkryłem, że po zainicjowaniu pól []
będą one współdzielone przez wszystkie obiekty Modelu. Wprowadzanie zmian w jednym wpływa na wszystkie pozostałe.
Nie zdarza się to przy ich inicjowaniu new Array()
. To samo dotyczy inicjalizacji obiektów (w {}
porównaniu z nowymi Object()
)
TBH Nie jestem pewien, czy jest to problem z używanym frameworkiem ( Dojo )
Jest w tym coś więcej niż na pierwszy rzut oka. Większość innych odpowiedzi jest poprawnych, ALE TAKŻE ..
new Array(n)
n
elementów[1, 2, 3] || []
delete
lub [1,,3]
składnia)for ..
, forEach
, map
, etc.)To chyba nie jest przypadek dla starszych przeglądarek wersji / przeglądarek.
Znalazłem jedną różnicę między tymi dwiema konstrukcjami, które mocno mnie ugryzły.
Powiedzmy, że mam:
function MyClass(){
this.property1=[];
this.property2=new Array();
};
var MyObject1=new MyClass();
var MyObject2=new MyClass();
W prawdziwym życiu, jeśli to zrobię:
MyObject1.property1.push('a');
MyObject1.property2.push('b');
MyObject2.property1.push('c');
MyObject2.property2.push('d');
Skończyłem z tym:
MyObject1.property1=['a','c']
MyObject1.property2=['b']
MyObject2.property1=['a','c']
MyObject2.property2=['d']
Nie wiem, co ma powiedzieć specyfikacja języka, ale jeśli chcę, aby moje dwa obiekty miały unikalne tablice właściwości w moich obiektach, muszę użyć new Array()
.
[]
i new Array()
konstruktorze, co daje jeden element na tablicę na właściwość. Musisz mieć coś innego w swoim kodzie, aby skończyć z wynikiem, który pokazałeś powyżej.
var property1static=[];
function MyClass(){ this.property1=property1static; this.property2=new Array(); };
Użycie konstruktora Array tworzy nową tablicę o pożądanej długości i zapełnia każdy indeks niezdefiniowanym, przypisana tablica do zmiennej tworzy indeksy, dla których podajesz informacje.
[]
Token:ARRAY_INIT
;new Array
tokeny:NEW, IDENTIFIER
;new Array()
tokeny:NEW, IDENTIFIER, CALL