Utworzyć pusty obiekt w JavaScript za pomocą {} czy nowego Object ()?

370

Istnieją dwa różne sposoby utworzenia pustego obiektu w JavaScript:

var objectA = {}
var objectB = new Object()

Czy jest jakaś różnica w sposobie obsługiwania ich przez silnik skryptów? Czy jest jakiś powód, aby używać jednego nad drugim?

Podobnie można również utworzyć pustą tablicę przy użyciu innej składni:

var arrayA = []
var arrayB = new Array()
Jonas Pegerfalk
źródło
6
Ostrzeżenie: istnieje niewielka różnica, która może powodować bardzo irytujące błędy! Utworzenie pustego obiektu przypisującego go do „{}” w prototypie Object będzie tą samą instancją Object w każdej instancji Object utworzonej przez „nowy” operator. Kiedy używasz „nowego obiektu ({})”, będziesz mieć różne instancje.
Peter - Przywróć Monikę
Warto wspomnieć, że oprócz tego var objectA = {} var objectB = new Object()istnieje trzeci konstrukt, który da ten sam rezultat:var objectC = Object.create(Object.prototype);
kalitsov
{}i [] Użyj {}zamiast new Object(). Użyj []zamiast new Array(). Użyj tablic, gdy nazwy członków będą sekwencyjnymi liczbami całkowitymi. Użyj obiektów, gdy nazwy członków są dowolnymi ciągami lub nazwami. źródło
ilgaar
new Object()i {}nie są całkiem pustymi obiektami, są to obiekty, które mają Object.prototype. Możesz użyć Object.create(null)do naprawdę pustego obiektu (przynajmniej zgodnie z dokumentacją mozilla: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )

Odpowiedzi:

459

Obiekty

Korzystanie z niego nie przynosi żadnych korzyści new Object();- {};może jednak uczynić kod bardziej zwartym i bardziej czytelnym.

Do definiowania pustych obiektów są one technicznie takie same. {}Składnia jest krótszy, neater (mniej Java-ish) i pozwala natychmiast wypełnić inline object - tak jak poniżej:

var myObject = {
        title:  'Frog',
        url:    '/img/picture.jpg',
        width:  300,
        height: 200
      };

Tablice

W przypadku tablic, podobnie prawie nie ma korzyści z używania new Array();ponad [];- z jednym drobnym wyjątkiem:

var emptyArray = new Array(100);

tworzy tablicę o długości 100 elementów ze wszystkimi gniazdami, undefinedktóre mogą być przydatne / przydatne w niektórych sytuacjach (np. (new Array(9)).join('Na-Na ') + 'Batman!').

Moja rekomendacja

  1. Nigdy nie używaj new Object();- jest bardziej nieprzyjemny {};i wygląda głupio.
  2. Zawsze używaj [];- z wyjątkiem sytuacji, gdy musisz szybko utworzyć „pustą” tablicę o zdefiniowanej długości.
Már Örlygsson
źródło
22
Nawet jeśli użyjesz składni Array (100), ta sama tablica na 101 pozycji jest w niej niezdefiniowana; jedyną rzeczą, którą tak naprawdę robi liczba, jest zmiana wartości właściwości length.
Jason Bunting
6
@Pablo nie ma w tym nic złego new Array(100). Przeczytaj literaturę: developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Már Örlygsson,
9
@Pablo Nie mam pojęcia, jaki jest twój argument. Podobnie jak Douglas Crockford, polecam używać []. Brak argumentów. Twierdziłeś jednak, że new Array(100)jest to „nieważne”, co jest nieprawdą.
Már Örlygsson
10
Należy również pamiętać, że new Array(1,2,3)wyniki w [1,2,3], ale new Array(1)ma nie powodować [1]; tak więc semantyka Arrayjest niespójna i niepotrzebnie zagmatwana.
Dancrumb
3
Dodałbym, że Object.create(null)może to być przydatne do utworzenia pustego obiektu, podczas gdy { }dziedziczy po prototypie Object.
Meow
90

Tak, jest różnica, to nie to samo. To prawda, że ​​uzyskasz te same wyniki, ale silnik działa w inny sposób dla obu z nich. Jeden z nich to dosłowny obiekt, a drugi to konstruktor, dwa różne sposoby tworzenia obiektu w javascript.

var objectA = {} //This is an object literal

var objectB = new Object() //This is the object constructor

W JS wszystko jest obiektem, ale powinieneś pamiętać o następującej rzeczy z nowym Object (): Może otrzymać parametr, i w zależności od tego parametru utworzy ciąg, liczbę lub po prostu pusty obiekt.

Na przykład: new Object(1)zwróci liczbę. new Object("hello")zwróci ciąg znaków, oznacza to, że konstruktor obiektu może delegować - w zależności od parametru - tworzenie obiektu innym konstruktorom, takim jak ciąg, liczba itp. ... Bardzo ważne jest, aby o tym pamiętać, zarządzając danymi dynamicznymi tworzyć obiekty ..

Wielu autorów zaleca, aby nie używać konstruktora obiektów, gdy można zamiast tego użyć pewnej literalnej notacji, dzięki czemu będziesz mieć pewność, że to, co tworzysz, jest tym, czego oczekujesz w kodzie.

Sugeruję, abyś przeczytał dalej na temat różnic między notacją literalną a konstruktorami javascript, aby znaleźć więcej szczegółów.

Guillermo Snipe
źródło
Zapis literalny jest w rzeczywistości bardziej czytelny i zwięzły, aby tworzyć dynamiczne obiekty danych.
Sid
12

Mają ten sam wynik końcowy, ale dodam po prostu, że użycie składni literałowej może pomóc przyzwyczaić się do składni JSON (podzbiór ciągów znaków dosłownej składni JavaScript), więc może być dobrą praktyką wchodzenie w .

Jeszcze jedno: możesz mieć subtelne błędy, jeśli zapomnisz użyć newoperatora. Używanie literałów pomoże ci uniknąć tego problemu.

Ostatecznie będzie to zależeć od sytuacji, a także preferencji.

Jason Bunting
źródło
8

Składnia literałów obiektowych i tablicowych {} / [] została wprowadzona w JavaScript 1.2, więc nie jest dostępna (i spowoduje błąd składniowy) w wersjach Netscape Navigator wcześniejszych niż 4.0.

Moje palce wciąż domyślnie wypowiadają nową Array (), ale jestem bardzo starym człowiekiem. Na szczęście Netscape 3 nie jest przeglądarką, którą wiele osób musi dziś rozważyć ...

Bobin
źródło
11
Netscape 3? Człowieku, to było w poprzednim wieku ! :-D
Tomalak
8
var objectA = {}

jest znacznie szybsza i z mojego doświadczenia wynika, że ​​jest częściej stosowana, więc prawdopodobnie najlepiej jest przyjąć „standard” i zaoszczędzić trochę pisania.

Bobby Jack
źródło
1
Szybciej uruchomić, czy po prostu szybciej pisać?
hippietrail
Cóż, co prawda, miałem na myśli „pisać”, ale biorąc pod uwagę dodatkowy czas analizowania, prawdopodobnie również nieco szybsze wykonanie :-)
Bobby Jack
2
Co więcej, literały są zwykle tworzone w czasie analizy, podczas gdy new Objectmuszą być wykonywane w czasie wykonywania.
Phrogz
8

Uważam, że {}został zalecony w jednym z vids Javascript tutaj jako dobra konwencja kodowania. newjest niezbędny do dziedziczenia pseudoklasycznego. var obj = {};sposób pomaga przypomnieć, że nie jest to klasyczny język zorientowany obiektowo, ale prototypal jeden. Tak więc jedyny czas, którego naprawdę potrzebujesz new, to korzystanie z funkcji konstruktora. Na przykład:

var Mammal = function (name) {
  this.name = name;
};

Mammal.prototype.get_name = function () {
  return this.name;
}

Mammal.prototype.says = function() {
  return this.saying || '';
}

Następnie używa się go tak:

var aMammal = new Mammal('Me warm-blooded');
var name = aMammal.get_name();

Kolejną zaletą używania {}w przeciwieństwie do tego new Objectjest to, że można go używać do literałów obiektowych w stylu JSON.

Thedric Walker
źródło
7

Wydajność tworzenia instancji macierzy

Jeśli chcesz utworzyć tablicę bez długości:

var arr = []; jest szybszy niż var arr = new Array();

Jeśli chcesz utworzyć pustą tablicę o określonej długości:

var arr = new Array(x); jest szybszy niż var arr = []; arr[x-1] = undefined ;

Aby przeprowadzić testy porównawcze, kliknij: https://jsfiddle.net/basickarl/ktbbry5b/

Nie znam jednak śladu pamięci obu, mogę sobie wyobrazić, że new Array()zajmuje więcej miejsca.

K - Toksyczność w SO rośnie.
źródło
arr = new Array(x)jest równoznaczne z arr = []; arr.length = x;nieprzypisywaniem x-1indeksu za pomocą undefined.
Bergi
2

To jest zasadniczo to samo. Używaj tego, co uważasz za wygodniejsze.

Tomalak
źródło
Być może zagłębiam się tutaj w javascript, ale czy są takie same? Czy {proto} nie Objectjest puste, a {proto} {}to „Object.prototype”?
Izhaki
@Izhaki Prototyp Objectjest zerowy, to prawda. To dlatego, że Objectkończy łańcuch prototypów. Instancje obiektów nie mają jednak prototypu, mają go tylko konstruktorzy. I (new Object()).constructor === ({}).constructor->true
Tomalak
Więc to jest nieprawidłowe?
Izhaki,
Oto moja uwaga: new Object()zwraca pustą instancję Object. {}zwraca pustą instancję Object. Oba te przypadki są absolutnie nie do odróżnienia. Przykład, do którego linkujesz, robi coś innego (modyfikuje łańcuch prototypów) i tak naprawdę nie ma tu zastosowania - lub nie rozumiem twojego argumentu.
Tomalak
1

OK , są tylko 2 różne sposoby na zrobienie tego samego! Jeden jest wywoływany, object literala drugi jest funkcją constructor!

Ale czytaj dalej, jest kilka rzeczy, którymi chciałbym się podzielić:

Użycie {}sprawia, że ​​kod jest bardziej czytelny, a tworzenie instancji Objectlub innych wbudowanych funkcji nie jest zalecane ...

Ponadto funkcja Object pobiera parametry, ponieważ jest funkcją, na przykład Object(params)... ale{} jest czystym sposobem na uruchomienie obiektu w JavaScript ...

Używanie literału obiektowego sprawia, że ​​kod wygląda na znacznie czystszy i łatwiejszy do odczytania dla innych programistów, co jest zgodne z najlepszymi praktykami w JavaScript ...

Podczas gdy obiekt w JavaScript może być prawie wszystkim, {}tylko wskazuje na obiekty javascript, aby sprawdzić, jak to działa, wykonaj poniżej w kodzie javascript lub konsoli:

var n = new Object(1); //Number {[[PrimitiveValue]]: 1}

Zaskakujące, że tworzy liczbę!

var a = new Object([1,2,3]); //[1, 2, 3]

I to tworzy tablicę!

var s = new Object('alireza'); //String {0: "a", 1: "l", 2: "i", 3: "r", 4: "e", 5: "z", 6: "a", length: 7, [[PrimitiveValue]]: "alireza"}

i ten dziwny wynik dla String!

Więc jeśli tworzysz obiekt, zaleca się użycie literału obiektowego, aby mieć standardowy kod i uniknąć jakiegokolwiek wypadku kodu, jak wyżej, również z punktu widzenia wydajności {}lepsze jest moje doświadczenie!

Alireza
źródło
jesteś Dezfooli? w Iranie?
Ehsan,
Cześć Ehsan, tak, ale nie mieszkam w Iranie, masz tutaj świetny profil! Miło cię poznać ...
Alireza,
czy mogę zapisać numer telefonu i uzyskać pomoc w zakresie programowania?
Ehsan,
Widzę, że używasz telegramu.
Ehsan,
Tak, na pewno możemy podzielić się pewną wiedzą na temat telegramu! ___
Alireza,