Jaka jest różnica między tą opartą na konstruktorach 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 dosłownej do obiektów.
Który jest lepszy i dlaczego?
javascript
object
jslint
typ
źródło
źródło
a = new Object
,a = new Object()
,a = {}
, dosłowny jest znacznie prostsze, a niektóre testy wpadłem przed chwilą powiedzieć, że jest szybciej, nowsze kompilatory mogą powodować moje oświadczenie, że są fałszywe. To samo dotyczy tablic dosłownychvar
słowem kluczowym w kodzie aplikacji, aby uniknąć zanieczyszczenia globalnej przestrzeni nazw i stworzyć potrzebę szukania zmiennych poza bieżącym rekordem w stosie.new
jest konwencją, która wykracza poza bezsensowne dręczenie przeciętnego języka. Użyj,new
ponieważ jego znaczenie jest jasne. W 99,9% przypadków wzrost wydajności nie ma znaczenia.Odpowiedzi:
Obaj robią to samo (chyba że ktoś zrobił coś niezwykłego), poza tym, że twój drugi tworzy obiekt i dodaje do niego właściwość. Ale notacja dosłowna zajmuje mniej miejsca w kodzie źródłowym. To jest wyraźnie rozpoznawalne, co się dzieje, więc korzystanie
new Object()
, naprawdę piszesz więcej i (teoretycznie, jeśli nie jest zoptymalizowany przez silnik JavaScript), wykonuje niepotrzebne wywołanie funkcji.Te
technicznie nie rób tego samego. Pierwszy po prostu tworzy obiekt. Drugi tworzy jeden i przypisuje właściwość. Aby pierwszy był taki sam, potrzebujesz drugiego kroku, aby utworzyć i przypisać właściwość.
„Coś niezwykłego”, co ktoś mógłby zrobić, to ukryć lub przypisać do domyślnego
Object
globalnego:W tym bardzo nietypowym przypadku
new Object
zawiedzie, ale{}
zadziała.W praktyce nigdy nie ma powodów, by używać
new Object
zamiast{}
(chyba, że zrobiłeś coś bardzo niezwykłego).źródło
()
new Object()
nie jest wymagane. (mówiąc o niepotrzebnych rzeczach)Prosty obiekt nie ma różnicy bez metod jak w twoim przykładzie. Jest jednak duża różnica, gdy zaczynasz dodawać metody do swojego obiektu.
Dosłowny sposób:
Prototypowy sposób:
Oba sposoby pozwalają na tworzenie takich instancji
Obj
:Jednak dosłownie przenosisz kopię
sayHello
metody w każdej instancji twoich obiektów. Natomiast w sposób prototypowy metoda jest zdefiniowana w prototypie obiektu i współdzielona między wszystkimi instancjami obiektów. Jeśli masz wiele obiektów lub wiele metod, dosłowny sposób może prowadzić do dość dużych strat pamięci.źródło
new Object()
vs{}
do tworzenia pustych obiektów.W JavaScript możemy zadeklarować nowy pusty obiekt na dwa sposoby:
Nie znalazłem niczego, co sugerowałoby, że istnieje jakakolwiek znacząca różnica między tymi dwoma, jeśli chodzi o sposób, w jaki działają za kulisami (proszę mnie poprawić, jeśli się mylę - chciałbym wiedzieć). Jednak druga metoda (wykorzystująca notację dosłowną obiektu) ma kilka zalet.
Rozważ nowy obiekt, który zawiera elementy Nazwa i numer telefonu. Korzystając z nowej konwencji Object (), możemy stworzyć ją w następujący sposób:
Te właściwości EXPANDO cechą JavaScript pozwala nam tworzyć nowych członków w ten sposób na bieżąco, i osiągnąć to, co zostało zamierza. Jednak ten sposób nie jest zbyt ustrukturyzowany ani zamknięty. Co by było, gdybyśmy chcieli określić członków podczas tworzenia, bez konieczności polegania na właściwościach expando i zadaniu po utworzeniu?
W tym przypadku literalna notacja obiektowa może pomóc:
Tutaj osiągnęliśmy ten sam efekt w jednym wierszu kodu i znacznie mniej znaków.
Dalszą dyskusję na temat powyższych metod budowy obiektów można znaleźć na stronie: JavaScript i programowanie obiektowe (OOP).
I w końcu, co z idiotą, który przesłonił Object? Myślałeś, że to niemożliwe? Cóż, ten JSFiddle dowodzi, że jest inaczej. Użycie literalnej notacji przedmiotowej zapobiega popełnianiu przez nas tego zboczenia.
(Od http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/ )
źródło
new Object()
powodu możliwości, że coś nadpisało funkcję Object, powinieneś także pisać strażników w dowolnym miejscu, gdy używasz pomocników,Object.keys
aby upewnić się, że nie jest niezdefiniowana, co popada w absurd. Zawsze polecałbym ludziom używanie dosłownego zapisu, ale myślę, że ten konkretny argument rozpada się, gdy myślisz o konsekwencjach takiego myślenia.Na moim komputerze za pomocą Node.js uruchomiłem następujące:
Uwaga: jest to rozszerzenie tego, co można znaleźć tutaj: Dlaczego arr = [] jest szybszy niż arr = new Array?
mój wynik był następujący:
więc wyraźnie {} i [] są szybsze niż używanie nowych do tworzenia pustych obiektów / tablic.
źródło
Wszyscy tutaj mówią o podobieństwach tych dwóch. Wskażę różnice.
Używanie
new Object()
pozwala mi przekazać kolejny obiekt. Oczywistym rezultatem jest to, że nowo utworzony obiekt zostanie ustawiony na to samo odwołanie. Oto przykładowy kod:Użycie nie jest ograniczone do obiektów jak w obiektach OOP. Można do niego również przekazać inne typy. Funkcja odpowiednio ustawi typ. Na przykład, jeśli przekażemy mu liczbę całkowitą 1, zostanie dla nas utworzony obiekt typu numer.
Obiekt utworzony za pomocą powyższej metody (
new Object(1)
) zostanie przekonwertowany na typ obiektu, jeśli zostanie do niego dodana właściwość.Jeśli obiekt jest kopią podrzędnej klasy obiektu, możemy dodać właściwość bez konwersji typu.
źródło
str
jest typu,string
więc nie można przypisać do niego właściwości. jsfiddle.net/grq6hdx7/1var obj = new Object("foo"); typeof obj; obj === "foo" // true
W rzeczywistości istnieje kilka sposobów tworzenia obiektów w JavaScript. Gdy chcesz po prostu utworzyć obiekt, tworzenie obiektów „ opartych na konstruktorze ” nie jest korzystne przy użyciu operatora „ nowy ”. To samo, co tworzenie obiektu przy użyciu składni „ dosłowny obiekt ”. Ale obiekty „ oparte na konstruktorach ” utworzone za pomocą „ nowego ” operatora stają się niezwykle przydatne, gdy myślisz o „ dziedziczeniu prototypowym ”. Nie można utrzymać łańcucha dziedziczenia z obiektami utworzonymi w dosłownej składni. Ale możesz utworzyć funkcję konstruktora , dołączyć właściwości i metody do jej prototypu."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 objaśnienie kodu na dole):
Teraz możesz utworzyć dowolną liczbę obiektów, tworząc instancję funkcji budowy Osoby, a wszystkie z nich 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 Person za pomocą operatora „ new ”, automatycznie zwróci obiekt zawierający wszystkie właściwości i metody powiązane ze słowem kluczowym „ this ” . Obiekt ten z pewnością odziedziczy metody i właściwości związane z prototypem funkcji konstruktora Person (co jest główną zaletą tego podejścia).
Nawiasem mówiąc, jeśli chcesz uzyskać tę samą funkcjonalność ze składnią „ dosłowny obiekt ”, musisz utworzyć pełną nazwę () na wszystkich obiektach, takich jak poniżej:
Na koniec, jeśli teraz zapytacie, dlaczego powinienem używać podejścia funkcji konstruktora zamiast dosłowności obiektowej :
*** Dziedziczenie prototypowe umożliwia prosty łańcuch dziedziczenia, który może być niezwykle użyteczny i potężny.
*** Oszczędza pamięć, dziedzicząc typowe 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.
źródło
Object.create(<object defined using literal notation>)
lubnew Object(<object defined using literal notation>)
tworzyć łańcuchy spadkowe.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(); // Zubaer Ahammed john.fullname(); // John Doe zubaer.constructor.prototype.fullname = function() { console.log( 'Hello ' + this.firstname); } zubaer.fullname(); // Hello Zubaer john.fullname(); // Hoello John
Ponadto, według niektórych książek O'Really javascript .... (cytowany)
Innym powodem używania literałów w przeciwieństwie do konstruktora obiektów jest brak rozdzielczości zakresu. Ponieważ możliwe jest, że utworzono lokalnego konstruktora o tej samej nazwie, interpreter musi wyszukać łańcuch zasięgu od miejsca, w którym wywołujesz Object (), aż do znalezienia globalnego konstruktora Object.
źródło
Znalazłem jedną różnicę dla ES6 / ES2015. Nie można zwrócić obiektu za pomocą składni funkcji skrótu, chyba że obiekt zostanie otoczony
new Object()
.Wynika to z tego, że kompilator jest pomieszany w
{}
nawiasach i myśli, żen: i
jest etykietą: instrukcja konstrukcja; średnik jest opcjonalny, więc nie narzeka.Jeśli dodasz inną właściwość do obiektu, w końcu wygeneruje błąd.
źródło
[1, 2, 3].map(v => { return {n: v}; });
przyniesie ci to samo ...param => return_value
I różnica między używaniem{}
anew Object()
w tym przypadku.[1, 2, 3].map(v => ({n: v}));
Aktualizacja 2019
Uruchomiłem ten sam kod co @rjloura na moim węźle OSX High Sierra 10.13.6 w wersji 10.13.0 i to są wyniki
źródło
Zużycie pamięci jest inne, jeśli utworzysz 10 tysięcy instancji.
new Object()
zachowa tylko jedną kopię, a{}
zachowa 10 000 kopii.źródło
new
tworzy nowy obiekt. Obie zajmują taką samą ilość pamięci.