Jaka jest różnica między 'new Object ()' a literalną notacją obiektu?

Jaka jest różnica pomiędzy składnią tego konstruktora przy tworzeniu obiektu:

person = new Object()

...i ta dosłowna składnia:

person = {
    property1 : "Hello"
};

Wygląda na to, że oba robią to samo, chociaż JSLint preferuje używanie obiektowej notacji dosłownej.

Która jest lepsza i dlaczego?
Author: apsillers, 2011-01-04

12 answers

Oboje robią to samo (chyba że ktoś zrobił coś niezwykłego), poza tym twój drugi tworzy obiekt i dodaje do niego właściwość. Ale dosłowna notacja zajmuje mniej miejsca w kodzie źródłowym. Jest to wyraźnie rozpoznawalne, co się dzieje, więc używając new Object(), tak naprawdę piszesz więcej i (teoretycznie, jeśli nie zoptymalizowany przez silnik JavaScript) wykonujesz niepotrzebne wywołanie funkcji.

Te

person = new Object() /*You should put a semicolon here too.  
It's not required, but it is good practice.*/ 
-or-

person = {
    property1 : "Hello"
};
Technicznie nie rób tego samego. Pierwszy po prostu tworzy obiekt. Drugi tworzy jeden i przypisuje właściwość. Aby pierwsza z nich była taka sama, musisz wykonać drugi krok, aby utworzyć i przypisać właściwość.

"czymś niezwykłym", które ktoś mógłby zrobić, byłoby cień lub przypisanie do domyślnego Object globalnego:

// Don't do this
Object = 23;

W tym bardzo nietypowym przypadku , new Object zawiedzie, ale {} zadziała.

W praktyce nigdy nie ma powodu, aby używać new Object zamiast {} (chyba, że zrobiłeś to bardzo nietypowa rzecz).

 128
Author: kemiller2002,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-03 11:10:35

Nie ma różnicy dla prostego obiektu bez metod, jak w twoim przykładzie. Jednak istnieje duża różnica, gdy zaczynasz dodawać metody do obiektu.

Sposób dosłowny:

function Obj( prop ) { 
    return { 
        p : prop, 
        sayHello : function(){ alert(this.p); }, 
    }; 
} 

Prototype way:

function Obj( prop ) { 
    this.p = prop; 
} 
Obj.prototype.sayHello = function(){alert(this.p);}; 

Oba sposoby pozwalają na tworzenie instancji Obj w następujący sposób:

var foo = new Obj( "hello" ); 

Jednakże, w sposób dosłowny, nosisz kopię metody sayHello w każdej instancji swoich obiektów. Natomiast w drodze prototypowej metoda jest zdefiniowana w obiekcie prototyp i współdzielone między wszystkimi instancjami obiektu. Jeśli masz dużo obiektów lub wiele metod, dosłowny sposób może prowadzić do dość dużego marnowania pamięci.

 239
Author: Rémy DAVID,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 23:44:58

W JavaScript możemy zadeklarować nowy pusty obiekt na dwa sposoby:

var obj1 = new Object();  
var obj2 = {};  

Nie znalazłem nic, co sugerowałoby, że istnieje jakaś znacząca różnica między tymi dwoma w odniesieniu do tego, jak działają za kulisami(Proszę mnie poprawić, jeśli się mylę-chciałbym wiedzieć). Jednak druga metoda (wykorzystująca obiektową notację dosłowną) ma kilka zalet.

  1. jest krótszy (dokładnie 10 znaków)
  2. łatwiejsze i bardziej ustrukturyzowane jest tworzenie obiektów na fly
  3. nie ma znaczenia, czy jakiś bufon nieumyślnie nadpisał obiekt

Rozważ nowy obiekt, który zawiera members Name i TelNo. Używając nowej konwencji Object (), możemy utworzyć ją w następujący sposób:

var obj1 = new Object();  
obj1.Name = "A Person";  
obj1.TelNo = "12345"; 

Właściwości Expando funkcja JavaScript pozwala nam tworzyć nowe członkowie w ten sposób w locie, i osiągamy to, co zamierzaliśmy. Jednak ten sposób nie jest zbyt zorganizowany ani zamknięty. Co jeśli chcemy określić członków na Tworzenie, bez konieczności polegania na właściwościach expando i przypisywaniu po utworzeniu?

Tutaj może pomóc literalna notacja obiektu:

var obj1 = {Name:"A Person",TelNo="12345"};  

Tutaj osiągnęliśmy ten sam efekt w jednej linii kodu i znacznie mniej znaków.

Dalsze omówienie powyższych metod budowy obiektów można znaleźć na stronie: JavaScript i programowanie obiektowe (OOP).

I wreszcie, co z idiotą, który przewrócił przedmiot? Myślałeś, że to nie możliwe? Cóż, ten JSFiddle dowodzi inaczej. Używanie dosłownej notacji obiektu uniemożliwia nam wpadnięcie w ten bufon.

(od http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/)

 56
Author: James Wiseman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-01 12:30:54

Na mojej maszynie używając Node.js, uruchomiłem:

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');

Uwaga, Jest to rozszerzenie tego, co znajduje się tutaj: Dlaczego arr = [] jest szybszy niż arr = new Array?

Mój wynik był następujący:

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

Tak wyraźnie {} i [] są szybsze niż używanie new do tworzenia pustych obiektów/tablic.

 41
Author: rjloura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:25

Wszyscy tutaj mówią o podobieństwach tych dwóch. Zwrócę uwagę na różnice.

  1. Użycie new Object() pozwala przekazać inny obiekt. Oczywistym rezultatem jest to, że nowo utworzony obiekt zostanie ustawiony na to samo odniesienie. Oto przykładowy kod:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
    
  2. Użycie nie jest ograniczone do obiektów jak w obiektach OOP. Inne typy mogą być przekazywane do niego zbyt. Funkcja odpowiednio ustawi Typ. Na przykład, jeśli przekażemy jej liczbę całkowitą 1, obiekt typu number zostanie stworzony dla nas.

    var obj = new Object(1);
    typeof obj // "number"
    
  3. Obiekt utworzony przy użyciu powyższej metody (new Object(1)) zostanie przekonwertowany na typ obiektu, jeśli zostanie do niego dodana właściwość.

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
    
  4. Jeśli obiekt jest kopią podrzędnej klasy obiektu, możemy dodać właściwość bez konwersji typu.

    var obj = new Object("foo");
    typeof obj // "object"
    obj === "foo" // true
    obj.a = 1;
    obj === "foo" // true
    obj.a // 1
    var str = "foo";
    str.a = 1;
    str.a // undefined
    
 32
Author: Jermin Bazazian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-09 00:20:14

W rzeczywistości istnieje kilka sposobów tworzenia obiektów w JavaScript. Jeśli chcesz tylko utworzyć obiekt, nie ma korzyści z tworzenia obiektów" opartych na konstruktorze "przy użyciu operatora" new". To tak samo jak tworzenie obiektu przy użyciu składni" object literal". Ale" constructor-based "objects created with" new "operator przychodzi do niesamowitego użytku, gdy myślisz o"prototypowego dziedziczenia ". Nie można utrzymać łańcucha dziedziczenia z obiekty tworzone z użyciem dosłownej składni. Ale możesz utworzyć funkcję konstruktora , dołączyć właściwości i metody do jej prototypu. Następnie przypisanie funkcji konstruktora do dowolnej zmiennej za pomocą operatora " new ", zwróci obiekt, który będzie miał dostęp do wszystkich metod i właściwości dołączonych do prototypu tej funkcji konstruktora.

Oto przykład tworzenia obiektu za pomocą funkcji konstruktora (Patrz wyjaśnienie kodu na dole):

function Person(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
}

Person.prototype.fullname = function() {
    console.log(this.firstname + ' ' + this.lastname);
}

var zubaer = new Person('Zubaer', 'Ahammed');
var john = new Person('John', 'Doe');

zubaer.fullname();
john.fullname();

Teraz możesz utworzyć dowolną liczbę obiektów, tworząc instancję funkcji Person construction i wszystkie z nich odziedziczą z niej fullname ().

Uwaga: Słowo kluczowe" this "będzie odnosić się do pustego obiektu wewnątrz funkcji konstruktora i za każdym razem, gdy utworzysz nowy obiekt od osoby używając operatora" new", automatycznie zwróci obiekt zawierający wszystkie właściwości i metody dołączone do słowa kluczowego" this". I te obiekty będą na pewno dziedziczą metody i właściwości dołączone do prototypu funkcji konstruktora persona (co jest główną zaletą tego podejścia).

Przy okazji, jeśli chcesz uzyskać tę samą funkcjonalność ze składnią " object literal ", musisz utworzyć fullname () na wszystkich obiektach, jak poniżej:

var zubaer = {
    firstname: 'Zubaer',
    lastname: 'Ahammed',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

var john= {
    firstname: 'John',
    lastname: 'Doe',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

zubaer.fullname();
john.fullname();

W końcu, jeśli teraz pytasz, dlaczego powinienem używać konstruktora funkcji approach zamiast obiekt dosłowny approach:

*** dziedziczenie prototypowe pozwala na prosty łańcuch dziedziczenia, który może być niezwykle użyteczny i potężny.

* * * zapisuje pamięć poprzez dziedziczenie wspólnych metod i właściwości zdefiniowanych w prototypie funkcji konstruktora. W przeciwnym razie musiałbyś kopiować je w kółko we wszystkich obiektach.

Mam nadzieję, że to ma sens.
 22
Author: Md. Zubaer Ahammed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-04 09:07:08

Również, według niektórych książek o ' really javascript....(cytat)

Innym powodem używania liter w przeciwieństwie do konstruktora obiektu jest brak rozdzielczości zakresu. Ponieważ jest możliwe, że stworzyłeś lokalny konstruktor o tej samej nazwie, interpreter musi sprawdzić łańcuch zakresu z miejsca, w którym wywołujesz Object() aż do momentu, gdy znajdzie globalny konstruktor obiektu.

 10
Author: adolfo_isassi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-22 18:25:54

Znalazłem jedną różnicę, dla ES6 / ES2015. Obiekt nie może być zwracany przy użyciu skróconej składni funkcji strzałki, chyba że otaczasz go znakiem new Object().

> [1, 2, 3].map(v => {n: v});
[ undefined, undefined, undefined ]
> [1, 2, 3].map(v => new Object({n: v}));
[ { n: 1 }, { n: 2 }, { n: 3 } ]

Jest to spowodowane tym, że kompilator jest zdezorientowany nawiasami {} i myśli, że n: i jest konstrukcjąlabel: statement ; średnik jest opcjonalny, więc nie narzeka na to.

Jeśli dodasz inną właściwość do obiektu, w końcu spowoduje to wyświetlenie błędu.

$ node -e "[1, 2, 3].map(v => {n: v, m: v+1});"
[1, 2, 3].map(v => {n: v, m: v+1});
                           ^

SyntaxError: Unexpected token :
 3
Author: Andrei Simionescu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-14 16:56:43

2019 Update

Uruchomiłem ten sam kod co @rjloura na moim OSX High Sierra 10.13.6 node w wersji 10.13.0 i oto wyniki

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');


Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms
 1
Author: PirateApp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-13 15:36:46

Jedyny czas, kiedy użyję' new ' keyowrd do inicjalizacji obiektu jest w funkcji strzałki inline:

() => new Object({ key: value})

Ponieważ poniższy kod jest nieprawidłowy:

() => { key: value} //  instead of () => { return { key: value};}
 0
Author: John Libes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-10 03:45:00

Jest tu wiele świetnych odpowiedzi, ale chcę przyjść z moimi 50 centami.

To, czego wszystkich tych odpowiedzi brakuje, to prosta analogia, która sprawdziłaby się dla osoby, która dopiero zaczyna swoją podróż w językach programowania.

Mam nadzieję, że wypełnię tę lukę tą analogią:

Tworzenie obiektów a składnia oparta na Konstruktorze

Poczuj różnicę w tworzeniu zdania.

Jeśli mam zdanie "I like cheese", mogę powiedzieć wyraźnie i głośno (dosłownie lub dosłownie): Lubię ser.

To jest moje dosłowne (słowo po słowie) stworzenie zdania.

Wszystkie inne sposoby są trudnymi sposobami, abyś zrozumiał, jakie zdanie dokładnie stworzyłem. Na przykład mówię ci:

  1. w moim zdaniu podmiotem jest "I", przedmiotem jest "cheese", a orzeczeniem jest "to like". Jest to kolejny sposób, aby nauczyć się bez żadnych niejasności tego samego zdania: "Lubię ser".

Lub

  1. mój zdanie ma 3 słowa: pierwszy z nich to słowo n-th w słowniku angielskim, drugi to słowo m-th w słowniku angielskim, a ostatni to słowo l-th w słowniku angielskim.

W tym przypadku, również dochodzisz do tego samego wyniku: wiesz dokładnie, co to jest zdanie.

Możesz opracować inne metody, które różnią się od tworzenia zdania" słowo po słowie " (dosłowne), a które byłyby pośrednie (nie dosłowne, nie dosłowne) metoda zdania stworzenie.

Myślę, że to jest podstawowa koncepcja, która się tu znajduje.
 0
Author: Andrew Anderson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-26 14:04:17

Użycie pamięci jest INNE, jeśli utworzysz 10 tysięcy instancji. new Object() zachowa tylko jedną kopię, podczas gdy {} zachowa 10 tysięcy kopii.

 -3
Author: Richard Miao US,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-19 09:58:29