Jaka jest różnica między new Object () a literałem obiektu notacji?


Jaka jest różnica między tą opartą na konstruktorze składnią tworzenia obiektu:
person = new Object()

...
i ta dosłowna składnia:
person = {
property1 : "Hello"
};

Wygląda na to, że oba robią to samo, chociaż JSLint woli używać notacji literału obiektowego.
Który jest lepszy i dlaczego?
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie ma różnicy w przypadku prostego obiektu bez metod takich jak Twój przykład.
Jednak istnieje duża różnica, gdy zaczynasz dodawać metody do obiektu.
Dosłownie:
function Obj( prop ) { 
return {
p : prop,
sayHello : function(){ alert(this.p); },
};
}

Prototypowy sposób:
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 w przypadku metody dosłownej przesyłasz kopię metody
sayHello
do każdej instancji swoich obiektów. Natomiast w przypadku metody prototypowej metoda jest zdefiniowana w prototypie obiektu i współdzielona przez wszystkie instancje obiektu.

Jeśli masz wiele obiektów lub metod, dosłowny sposób może doprowadzić do znacznej utraty pamięci.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oboje robią to samo (chyba że ktoś inny zrobił coś niezwykłego), z wyjątkiem tego, że twoja druga tworzy obiekt

i

dodaje do niego właściwość. Ale notacja dosłowna zajmuje mniej miejsca w kodzie źródłowym. Wyraźnie rozpoznaje, co się dzieje, więc używając
new Object ()
naprawdę piszesz więcej i (w teorii, jeśli nie jest zoptymalizowane 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. Pierwsza po prostu tworzy obiekt. Drugi tworzy go i przypisuje właściwość. Aby pierwsza była taka sama, musisz wykonać drugi krok, aby utworzyć i przypisać właściwość.
„Coś niezwykłego”, co ktoś mógłby zrobić, byłoby cieniem lub domyślnym przypisaniem globalnego elementu
Object
:
// Don't do this
Object = 23;

W tym

niezwykle niezwykłe

w przypadku, gdy
new Object
nie powiedzie się, ale
{}
będzie działać.
W praktyce nigdy nie ma powodu, aby używać
new Object
zamiast
{}
(chyba że zrobiłeś to bardzo niezwykłe).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W JavaScript możemy zadeklarować nowy pusty obiekt na dwa sposoby:
var obj1 = new Object(); 
var obj2 = {};

Nie znalazłem nic, co wskazywałoby na to, że istnieje jakaś znacząca różnica między tymi dwoma, jeśli chodzi o ich działanie za kulisami (proszę mnie poprawić, jeśli się mylę - chciałbym wiedzieć). Jednak druga metoda (wykorzystująca notację literału obiektowego) ma kilka zalet.
  • Jest krótszy (dokładnie 10 znaków)
  • Łatwiejsze i lepiej zorganizowane tworzenie obiektów w locie
  • Nie ma znaczenia, czy jakiś błazen przypadkowo przedefiniował przedmiot

Rozważ nowy obiekt zawierający nazwę elementu i TelNo. Korzystając z nowej konwencji Object (), możemy to utworzyć w następujący sposób:
var obj1 = new Object(); 
obj1.Name = "A Person";
obj1.TelNo = "12345";

Funkcjonować

Expando Properties
http://it.toolbox.com/blogs/th ... 18471
JavaScript pozwala nam w ten sposób na bieżąco tworzyć nowych członków i osiągamy to, co zamierzaliśmy. Jednak ta metoda nie jest zbyt zorganizowana ani zamknięta. A co, jeśli chcemy określić członków podczas tworzenia, bez polegania na właściwościach expando i przypisaniu po utworzeniu?
W tym miejscu może pomóc notacja dosłowna obiektu:
var obj1 = {Name:"A Person",TelNo="12345"};

Tutaj uzyskaliśmy ten sam efekt w jednej linii kodu i przy znacznie mniejszej liczbie znaków.
Dalsze omówienie powyższych metod budowy obiektów można znaleźć pod adresem:

JavaScript i programowanie obiektowe (OOP).
http://www.javascriptkit.com/j ... shtml
Wreszcie, co z tym idiotą, który przebiegł przez placówkę? Czy naprawdę myślisz, że to niemożliwe? Dobrze,

to JSFiddle
http://jsfiddle.net/Pdsr2/
dowodzi, że jest inaczej. Używanie notacji literalnej obiektu zapobiega wpadnięciu w błoto tej klaunowskiej gry.
(Od

http://www.jameswiseman.com/bl ... ation
http://www.jameswiseman.com/bl ... tion/
/)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Na moim komputerze korzystającym z Node.js uruchomiłem następujące czynności:
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');

Zauważ, że jest to rozszerzenie tego, co tutaj:

dlaczego arr = [] jest szybszy niż arr = new Array?
https://coderoad.ru/7375120/
mój wynik był następujący:
Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

więc oczywiście {} i [] są szybsze niż używanie new do tworzenia pustych obiektów/tablic.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wszyscy tutaj mówią o podobieństwach między nimi. Zwrócę uwagę na różnice.
  • Użycie
    new Object ()
    umożliwia przekazanie innego obiektu. 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
  • Użycie nie jest ograniczone do obiektów, jak w obiektach OOP. Można do niego również przenosić inne typy. Funkcja odpowiednio ustawi typ. Na przykład, jeśli podamy liczbę całkowitą 1, to zostanie dla nas utworzony obiekt typu numer.
    var obj = new Object(1);typeof obj// "number"
  • Obiekt utworzony powyższą metodą (
    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"
  • Jeśli obiekt jest kopią klasy potomnej obiektu, możemy dodać właściwość bez konwersji typu.
    var obj = new Object("foo");typeof obj// "object"obj === "foo"// trueobj.a = 1;obj === "foo"// trueobj.a// 1var str = "foo";str.a = 1;str.a// undefined
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W rzeczywistości istnieje kilka sposobów tworzenia obiektów w JavaScript. Kiedy chcesz tylko stworzyć obiekt, nie ma żadnej korzyści z tworzenia obiektów „on”

oparty na konstruktorze

„using the operator”

new

". To jest to samo, co tworzenie obiektu przy użyciu składni"

object literal

". Ale"

projekt

„obiekty utworzone za pomocą operatora”

new

„są niezwykle pomocne, gdy myślisz o”

dziedziczenie prototypowe

". Nie można zachować łańcucha dziedziczenia z obiektami utworzonymi przy użyciu składni literału. Ale można tworzyć

funkcja konstruktora
, dołącz właściwości i metody do swojego prototypu. Następnie, jeśli przypiszesz tę funkcję konstruktora do dowolnej zmiennej za pomocą „

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 przy użyciu funkcji konstruktora (zobacz wyjaśnienie kodu poniżej):
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 konstrukcji Person, a wszystkie one odziedziczą po niej fullname ().
Uwaga:
słowo kluczowe "

this

"będzie odnosić się do pustego obiektu w funkcji konstruktora i za każdym razem, gdy utworzysz nowy obiekt z człowieka za pomocą"

new

", automatycznie zwraca obiekt zawierający wszystkie właściwości i metody skojarzone ze słowem kluczowym"

this

". I te obiekty najprawdopodobniej odziedziczą metody i właściwości związane z

prototyp

Funkcje konstruktora Person (co jest główną zaletą tego podejścia).
Nawiasem mówiąc, jeśli chcesz uzyskać tę samą funkcjonalność ze składnią „

object literal

", będziesz musiał utworzyć pełną nazwę () na wszystkich obiektach, jak pokazano 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();

Wreszcie, jeśli teraz zapytasz, dlaczego powinienem stosować to podejście

funkcje konstruktora

zamiast podejścia

dosłowny obiekt

:
*** Dziedziczenie prototypowe umożliwia utworzenie prostego łańcucha dziedziczenia, który może być niezwykle użyteczny i potężny.
*** Oszczędza pamięć, dziedzicząc wspólne metody i właściwości zdefiniowane w prototypie funkcji konstruktora. W przeciwnym razie będziesz musiał kopiować je w kółko we wszystkich obiektach.
Mam nadzieję, że to ma sens.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ponadto, według niektórych książek javascript O'Really .... (cytowane)
Innym powodem używania literałów w przeciwieństwie do konstruktora obiektów jest brak rozdzielczości zakresu. Ponieważ jest możliwe, że utworzyłeś konstruktora lokalnego o tej samej nazwie, interpreter musi przeszukiwać łańcuch o określonym zakresie, z którego wywołano Object (), aż znajdzie globalny konstruktor obiektów.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Znalazłem jedną różnicę, dla ES6/ES2015. nie możesz zwrócić obiektu używając składni funkcji strzałki skrótu, chyba że otoczysz obiekt
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 } ]

Dzieje się tak, ponieważ kompilator jest zdezorientowany co do nawiasów
{}
i uważa, że ​​
n: i
to konstrukcja

label: statement
https://developer.mozilla.org/ ... label
; średnik jest opcjonalny, więc nie narzeka na to.
Jeśli dodasz inną właściwość do obiektu, w końcu zwróci to błąd.
$ 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 :
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Zaktualizuj 2019

Uruchomiłem ten sam kod co @rjloura na moim węźle OSX High Sierra 10.13.6 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
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jedyny przypadek, w którym użyję klawisza `` nowy '' do zainicjowania obiektu, to funkcja strzałki wbudowanej:
() => new Object({ key: value})

ponieważ poniższy kod jest nieprawidłowy:
() => { key: value}// instead of () => { return { key: value};}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wykorzystanie pamięci jest inne, jeśli utworzysz 10 tysięcy instancji.
new Object ()
będzie przechowywać tylko jedną kopię, a
{}
będzie zawierać 10 tysięcy instancji.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się